PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

errore:la sottoquery deve restituire solo una colonna

Inserisci una sottoquery che restituisca più colonne nel FROM elenco e selezionarlo.

Una sottoquery correlata sarebbe una cattiva idea per cominciare. Tuttavia, la tua query non è nemmeno correlata, ma non correlata (nessun collegamento alla query esterna) e sembra restituire più righe. Questo porta a (forse molto costoso e senza senso) cross join che producono un prodotto cartesiano, probabilmente non la tua intenzione (segreta).

Sembra che tu voglia davvero:

SELECT m1.mat AS mat1, m1.sumtotal AS sumtotal1
      ,m2.mat AS mat2, m2.sumtotal AS sumtotal2
FROM (
   SELECT mat.mat, sum(stx.total) AS sumtotal
   FROM   stx 
   LEFT   JOIN mat ON mat.matid = stx.matid
   LEFT   JOIN sale ON stx.saleid = sale.id
   WHERE  stx.date BETWEEN '2013-05-01' AND '2013-08-31'
   AND    sale.userid LIKE 'A%'
   GROUP  BY mat.mat
   ) m1
JOIN  (
   SELECT mat.mat, sum(stx.total) AS sumtotal
   FROM   stx 
   LEFT   JOIN mat ON mat.matid = stx.matid
   LEFT   JOIN sale ON sale.id = stx.saleid
   WHERE  stx.date BETWEEN '2013-05-01' AND '2013-08-31' 
   AND    sale.userid LIKE 'b%'
   GROUP  BY mat.mat
   ) m2 USING (mat);

Entrambi LEFT JOIN sono anche inutili. Quello in sale è forzato a un INNER JOIN dalla condizione WHERE. Quello sul tappetino sembra inutile, dal momento che GROUP BY mat.mat - salvo se sei interessato a mat IS NULL ? (Ne dubito.)

Il caso può probabilmente essere ulteriormente semplificato in:

SELECT m.mat
      ,sum(CASE WHEN s.userid LIKE 'A%' THEN x.total END) AS total_a
      ,sum(CASE WHEN s.userid LIKE 'B%' THEN x.total END) AS total_b
FROM   sale s 
JOIN   stx  x ON x.saleid = s.id
JOIN   mat  m ON m.matid = x.matid
WHERE (s.userid LIKE 'A%' OR s.userid LIKE 'B%')
AND    x.date BETWEEN '2013-05-01' AND '2013-08-31'
GROUP  BY 1;

Il WHERE condizione può probabilmente essere ulteriormente semplificata, a seconda dei tipi e degli indici di dati segreti. Un carico di informazioni proprio su quel caso in questa risposta correlata su dba.SE .