2016-09-17 8 views
1

を達成することができますすることができますどのように私は、サブクエリや方法によってグループがこれは私のクエリで私の出力

SELECT dte,((SELECT COUNT(prdt) as P1 FROM table 
WHERE prdt LIKE '%P1%' AND stat= 'Done' AND dte BETWEEN '08/01/2016' AND '09/07/2016') as P1, 

(SELECT COUNT(prdt) as P2 FROM table 
WHERE prdt LIKE '%P2%' AND stat= 'Done' AND dte BETWEEN '08/01/2016' AND '09/07/2016') as P2, 

(SELECT COUNT(prdt) as P3 FROM table 
WHERE prdt LIKE '%P3%' AND stat= 'Done' AND dte BETWEEN '08/01/2016' AND '09/07/2016') as P3 

FROM table WHERE dte BETWEEN '08/01/2016' AND '09/07/2016' GROUP BY dte 

テーブル

+-------------------+ 
| dte1 |prdct|stat| 
+--------+-----+----+ 
|8/1/2016| P1 |Done| 
+--------+-----+----+ 
|8/2/2016| P2 |Done| 
+--------+-----+----+ 
|8/3/2016| P1 |Done| 
+--------+-----+----+ 
|8/1/2016| P3 |Done| 
+--------+-----+----+ 

は、これは私が出力を望むものである:

+--------+----+----+----+ 
| Dte1 | P1 | P2 | P3 | 
+--------+----+----+----+ 
|8/1/2016| 1 |NULL| 1 | 
+--------+----+----+----+ 
|8/2/2016|NULL| 1 |NUll| 
+--------+----+----+----+ 
|8/3/2016| 1 |NULL|NULL| 
+--------+----+----+----+ 
+0

質問を編集して試したことを示す必要があります。 –

+0

私が望む出力を達成するために何を選択すればいいのですか? –

+0

誰も部屋のゾウについて言及しませんか? '08/01/2016 'とは何ですか?どうしたら何かの間にできますか? – Strawberry

答えて

2

SELECTリストにサブクエリーが必要なのはなぜですか?テーブルを何度もスキャンする必要はありません。

dte BETWEEN述語のリテラルは、DATEの値であるように見えます。しかし、それはDATEリテラルでは有効な形式ではありません。 dte列が文字列型(CHARまたはVARCHAR)で、dte列に日付の値を格納している場合は間違っています。

dte(文字列)の値が'08/15/1999'のクエリでは、文字列として比較されます。たとえば、次の条件をテストします。

SELECT '08/15/1999' BETWEEN '08/01/2016' AND '09/16/2016' 

真は真となります。 (文字列の比較に関しては、それは当てはまりますが、これらの値を日付として見ると、1999年の日付は2016年の2つの日付の間になるはずです)。

しかし、日付形式はさておき問題、そしてあなたが尋ねた質問に取り組む...


ちょうど 条件付き集約を使用してクエリを記述します。たとえば、次のようになります。

このクエリは「0」カウントを返しますが、これは仕様と一致しません。置き換える、より多くのANSI-の規格に準拠したバージョンについては

SELECT t.dte 
     , NULLIF(SUM(t.stat = 'Done' AND t.prdt LIKE '%P1%'),0) AS P1 
     , NULLIF(SUM(t.stat = 'Done' AND t.prdt LIKE '%P2%'),0) AS P2 
     , NULLIF(SUM(t.stat = 'Done' AND t.prdt LIKE '%P3%'),0) AS P3 
    FROM table t 
    WHERE t.dte BETWEEN '2016-08-01' AND '2016-09-07' 
    GROUP BY t.dte 

MySQLは

を速記:指定に一致し、ゼロの代わりにNULL値を返すために、私たちは便利な NULLIF機能を使用して、NULLをゼロカウントを置き換えることができます

SUM(CASE WHEN t.stat = 'Done' AND t.prdt LIKE '%P1%' THEN 1 END) 

NULLIF(SUM(t.stat = 'Done' AND t.prdt LIKE '%P1%'),0) 

SOMがある場合あなたがのSELECTリスト内でサブクエリを使用する必要がある場合は、相関サブクエリを使用できます。サブクエリ内の外部クエリからdteの値を参照するだけです。

SELECT t.dte 
    , (SELECT NULLIF(COUNT(*),0) 
      FROM table t1 
      WHERE t1.dte = t.dte 
      AND t1.prdt LIKE '%P1%' 
      AND t1.stat = 'Done' 
     ) AS P1 
    , (SELECT NULLIF(COUNT(*),0) 
      FROM table t2 
      WHERE t2.dte = t.dte 
      AND t2.prdt LIKE '%P2%' 
      AND t2.stat = 'Done' 
     ) AS P1 
    , (SELECT NULLIF(COUNT(*),0) 
      FROM table t3 
      WHERE t3.dte = t.dte 
      AND t3.prdt LIKE '%P3%' 
      AND t3.stat = 'Done' 
     ) AS P3 
    FROM table t 
    WHERE t.dte BETWEEN '2016-08-01' AND '2016-09-07' 
    GROUP BY t.dte 

SELECTリストで相関サブクエリを使用すると、通常、条件付き集約パターンを使用するよりもコストがかかります。これは、外部クエリによって返された各行に対してサブクエリが実行されるためです。外側のクエリが1000行を返した場合、サブクエリは1000回実行されます。

+0

これは私が欲しいものですありがとう –

関連する問題