web-dev-qa-db-ja.com

エラー:サブクエリは1つの列のみを返す必要があります

エラーが発生しますsubquery must return only one column次のクエリを実行しようとすると:

SELECT mat.mat as mat1, sum(stx.total ) as sumtotal1,
  (
    SELECT mat.mat  as mat, sum(stx.total)  as sumtotal
    FROM stx 
      LEFT JOIN mat ON stx.matid = mat.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
) AS MyField
FROM stx 
  LEFT JOIN mat ON stx.matid = mat.matid
  LEFT JOIN sale ON stx.saleid = sale.id
WHERE stx.date BETWEEN '2013-05-01' AND '2013-08-31'
  AND sale.userid LIKE 'B%'
GROUP BY mat.mat

このエラーの原因は何ですか?

13
user2431581

複数の列を返すサブクエリをFROMリストに入れ、そこから選択します。

相関サブクエリは、最初は悪い考えです。ただし、クエリは相関していませんが、unrelated(外部クエリへのリンクなし)であり、複数の行を返すようです。これは、(おそらく非常に高価で無意味な)クロスジョインを引き起こし、おそらく(秘密の)意図ではないデカルト積を生成します。

あなたが本当に望んでいるように見えます:

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

両方のLEFT JOINも無意味です。 sale上のものは、WHERE条件によってINNER JOINに強制されます。あなたがGROUP BY mat.mat-mat IS NULLに興味がある場合を除いて、マットの上のものは無意味に思えますか? (疑わしい。)

ケースはおそらくさらに単純化して次のようになります。

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条件は、秘密のデータ型とインデックスに応じて、おそらくさらに単純化できます。 この関連するdba.SEの回答 の場合の正確なケースに関する大量の情報。

14

サブクエリselectステートメントの代わりに

SELECT mat.mat  as mat, sum(stx.total)  as sumtotal

このステートメントを試してください

SELECT sum(stx.total)  as sumtotal
0
Snehal