PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

erreur :la sous-requête ne doit renvoyer qu'une seule colonne

Placez une sous-requête qui renvoie plusieurs colonnes dans le FROM liste et sélectionnez-la.

Une sous-requête corrélée serait une mauvaise idée pour commencer. Cependant, votre requête n'est même pas corrélée, mais non liée (pas de lien vers la requête externe) et semble renvoyer plusieurs lignes. Cela conduit à une jointure croisée (peut-être très coûteuse et absurde) produisant un produit cartésien, probablement pas votre intention (secrète).

Apparemment, vous voulez vraiment :

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);

Les deux LEFT JOIN sont également inutiles. Celui en sale est forcé à un INNER JOIN par la condition WHERE. Celui sur mat semble inutile, puisque vous GROUP BY mat.mat - sauf si vous êtes intéressé par mat IS NULL ? (J'en doute.)

Le cas peut probablement être encore simplifié en :

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;

Le WHERE condition peut probablement être simplifiée davantage, en fonction de vos types de données secrètes et de vos index. Une cargaison d'informations sur précisément ce cas dans cette réponse connexe sur dba.SE .