sql >> Databáze >  >> RDS >> PostgreSQL

chyba:poddotaz musí vrátit pouze jeden sloupec

Vložte poddotaz, který vrací více sloupců, do FROM seznam a vyberte z něj.

Korelovaný poddotaz by byl pro začátek špatný nápad. Váš dotaz však není ani korelovaný, ale nesouvisející (žádný odkaz na vnější dotaz) a zdá se, že vrací více řádků. To vede k (možná velmi drahému a nesmyslnému) křížovému spoji, který vytvoří kartézský produkt, což pravděpodobně není váš (tajný) záměr.

Vypadá to, že opravdu chcete:

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

Oba LEFT JOIN jsou také zbytečné. Ten v sale je vynucen k INNER JOIN podle podmínky KDE. Ten na podložce se zdá zbytečný, protože GROUP BY mat.mat - kromě případů, kdy vás zajímá mat IS NULL ? (O tom pochybuji.)

Případ lze pravděpodobně dále zjednodušit na:

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;

WHERE stav lze pravděpodobně dále zjednodušit v závislosti na vašich tajných typech dat a indexech. Spousta informací přesně o tomto případu v tato související odpověď na dba.SE .



  1. Jak získávání posledního ID vložení mysql funguje s transakcemi? + transakční otázky

  2. Zapište soubor na SFTP pomocí Oracle PL/SQL

  3. Jak načíst řádek v tabulce DB právě přidané v Javě

  4. Přepnutí oddílu na serveru SQL (T-SQL)