SQL仅在所有行符合条件时才选择行

时间:2012-11-16 06:58:08

标签: java sql

我对SQL很陌生,虽然我可以编写大部分查询,但我无法使用这个查询。我想在一个可以使用JPA执行的查询中实现这一点。

TABLE RULE:
RULE_ID   ENABLED
-----------------
1         0
2         0
3         0
4         1
5         1

TABLE MISC:
MISC_ID
--------
1
2

TABLE HOLD:
HOLD_ID   MISC_ID   RULE_ID   READY
------------------------------------
1         1         1         1       
2         1         2         1       
3         1         3         1       
4         2         4         0      
5         2         1         1       

我想从HOLD中仅选择MISC_ID,其中每行的READY = 1且RULE_ID在(RULE_IDs,其中ENABLED = 0)。在上面的示例中,查询应返回MISC_ID = {1},因为HOLD_IDs 1,2和3都具有READY = 1且RULEs 1,2和3都被禁用。

由于HOLD_ID 4的READY = 0,因此不应返回MISC_ID 2.

表MISC和HOLD有数百万行但RULE相当小(<1000行)。

有关如何编写本机SQL以实现此目的的任何建议? PL / SQL不是一个选项。

3 个答案:

答案 0 :(得分:2)

SELECT MISC_ID
FROM HOLD

GROUP BY MISC_ID
HAVING MIN(READY) <> 0;

示例运行:

$ with HOLD (HOLD_ID, MISC_ID, RULE_ID, READY)
as (values
    (1,1,1,1),
    (2,1,2,1),
    (3,1,3,1),
    (4,2,4,0),
    (5,2,1,1)
)

select MISC_ID
from HOLD

group by MISC_ID
having min(READY) <> 0;

 misc_id
---------
       1
(1 row)

修改查询以处理加入规则:

SELECT HOLD.*, RULE.*

FROM HOLD

INNER JOIN RULE
ON HOLD.RULE_ID = RULE.RULE_ID AND RULE.ENABLED = 0

WHERE MISC_ID IN (
    SELECT MISC_ID
    FROM HOLD

    GROUP BY MISC_ID
    HAVING MIN(READY) <> 0
);

答案 1 :(得分:1)

使用HAVING并匹配计数:

SELECT MISC_ID
FROM HOLD h
WHERE READY = 1
GROUP BY MISC_ID
HAVING COUNT(*) = (SELECT COUNT(*) FROM HOLD h2 WHERE h2.MISC_ID = h.MISC_ID)

或者,在自身上使用反连接:

SELECT DISTINCT MISC_ID
FROM HOLD h
LEFT OUTER JOIN HOLD h2 ON h.MISC_ID = h2.MISC_ID AND h2.READY <> 1
WHERE h2.MISC_ID IS NULL

或者,使用HAVING并比较MIN和MAX值:

SELECT MISC_ID
FROM HOLD
GROUP BY MISC_ID
HAVING MIN(READY) = 1 AND MAX(READY) = 1

答案 2 :(得分:0)

试试这个::

    Select * from TABLE_HOLD th

    group by MISC_ID

left join

(    Select MISC_ID from TABLE_HOLD

    group by MISC_ID having READY=0 ) temp_table on (th.MISC_ID=temp_table.MISC_ID)
where temp_table.HOLD_ID is null