2013-08-22 66 views
0

我有一個表:SQL:獲取鏈接到一個項目的多個行條目?

ID | ITEMID | STATUS | TYPE 
1 | 123 | 5  | 1 
2 | 123 | 4  | 2 
3 | 123 | 5  | 3 
4 | 125 | 3  | 1 
5 | 125 | 5  | 3 

任何項目可以有0到這個表中的許多條目。我需要一個查詢,會告訴我,如果項目已在任何一個5或4州的所有它的條目例如,在上面的例子中,我想,結果落得:

ITEMID | REQUIREMENTS_MET 
123 | TRUE --> true because all statuses are either 5 or 4 
125 | FALSE --> false because it has a status of 3 and a status of 5. 
        If the 3 was a 4 or 5, then this would be true 

什麼會更好是這樣的:

ITEMID | MET_REQUIREMENTS | NOT_MET_REQUIREMENTS 
123 | 3    | 0 
125 | 1    | 1 

任何想法如何編寫一個查詢呢?

+0

缺失:表定義,Postgres版本。任何列可以是NULL嗎? –

回答

2

快速,簡短,簡單:

SELECT itemid 
     ,count(status = 4 OR status = 5 OR NULL) AS met_requirements 
     ,count(status < 4 OR status > 5 OR NULL) AS not_met_requirements 
FROM tbl 
GROUP BY itemid 
ORDER BY itemid; 

假設所有列都是integer NOT NULL

構建於basic boolean logic
TRUE OR NULL產生TRUE
FALSE OR NULL產生NULL

和NULL不受count()計數。

->SQLfiddle demo.

0

簡單:

select 
    "ITEMID", 
    case 
     when min("STATUS") in (4, 5) and max("STATUS") in (4, 5) then 'True' 
     else 'False' 
    end as requirements_met 
from table1 
group by "ITEMID" 

更好的:

select 
    "ITEMID", 
    sum(case when "STATUS" in (4, 5) then 1 else 0 end) as MET_REQUIREMENTS, 
    sum(case when "STATUS" in (4, 5) then 0 else 1 end) as NOT_MET_REQUIREMENTS 
from table1 
group by "ITEMID"; 

sql fiddle demo

0
SELECT a.ID FROM (SELECT ID, MIN(STATUS) AS MINSTATUS, MAX(STATUS) AS MAXSTATUS FROM TABLE_NAME AS a GROUP BY ID) 
WHERE a.MINSTATUS >= 4 AND a.MAXSTATUS <= 5 
+1

這是行不通的 - 它不會顯示任何帶有「FALSE」的行 –

+0

你是對的Aleks G,我只想顯示一個可能的方法嵌套選擇 – xrodas

0

一個這樣做的方法是

SELECT t1.itemid, NOT EXISTS(SELECT 1 
          FROM mytable t2 
          WHERE itemid=t1.itemid 
          AND status NOT IN (4, 5)) AS requirements_met 
FROM mytable t1 
GROUP BY t1.itemid 

更新:爲您更新的要求,你可以有這樣的:

SELECT itemid, 
     sum(CASE WHEN status IN (4, 5) THEN 1 ELSE 0 END) as met_requirements, 
     sum(CASE WHEN status IN (4, 5) THEN 0 ELSE 1 END) as not_met_requirements 
FROM mytable 
GROUP BY itemid 
-1

沒關係,這是很容易做到的:

select ITEM_ID , 
    sum (case when STATUS >= 3 then 1 else 0 end) as met_requirements, 
    sum (case when STATUS < 3 then 1 else 0 end) as not_met_requirements 
from TABLE as d 
group by ITEM_ID 
+1

這是不正確的 –

+0

那麼它是正確的?它給了我想要的結果? – coderama

+0

檢查sql小提琴 - http://sqlfiddle.com/#!12/1f0a7/10 –

0
WITH dom AS (
     SELECT DISTINCT item_id FROM items 
     ) 
,  yes AS (SELECT item_id, COUNT(*) AS good_count FROM items WHERE status IN (4,5) GROUP BY item_id 
     ) 
,  no AS (SELECT item_id, COUNT(*) AS bad_count FROM items WHERE status NOT IN (4,5) GROUP BY item_id 
     ) 
SELECT d.item_id 
     , COALESCE(y.good_count,0) AS good_count 
     , COALESCE(n.bad_count,0) AS bad_count 
FROM dom d 
LEFT JOIN yes y ON y.item_id = d.item_id 
LEFT JOIN no n ON n.item_id = d.item_id 
     ; 

可以與外部進行連接:

WITH yes AS (SELECT item_id, COUNT(*) AS good_count FROM items WHERE status IN (4,5) GROUP BY item_id) 
,  no AS (SELECT item_id, COUNT(*) AS bad_count FROM items WHERE status NOT IN (4,5) GROUP BY item_id) 
SELECT COALESCE(y.item_id, n.item_id) AS item_id 
    , COALESCE(y.good_count,0) AS good_count 
    , COALESCE(n.bad_count,0) AS bad_count 
FROM yes y 
FULL JOIN no n ON n.item_id = y.item_id 
    ;