0

我有一张桌子:

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 到多个条目。我需要一个查询来告诉我一个 ITEM 的所有条目是否处于 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

知道如何为此编写查询吗?

4

6 回答 6

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.

建立在基本布尔逻辑之上:
TRUE OR NULL 产生TRUE
FALSE OR NULL产量 NULL

并且 NULL 不计入count().

->SQLfiddle 演示。

于 2013-08-22T19:12:31.933 回答
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

于 2013-08-22T08:47:08.623 回答
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
于 2013-08-22T08:48:34.340 回答
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
于 2013-08-22T08:50:05.387 回答
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
    ;
于 2013-08-22T09:20:50.130 回答
-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
于 2013-08-22T08:52:20.293 回答