2012-11-16 42 views
3

我很新的SQL,虽然我能得到周围写大多数查询,我没有在任何地方与这一个得到。我想在一个可以使用JPA执行的查询中实现这一点。SQL选择行只有当所有的人都符合标准

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_IDs其中每行具有READY = 1和RULE_ID是在(RULE_IDs其中ENABLED = 0)。在上面的例子中,查询应该返回MISC_ID = {1},因为HOLD_IDs 1,2和3都有READY = 1,而RULEs 1,2和3都被禁用。

MISC_ID 2不应该返回因为HOLD_ID 4具有READY = 0。

的表MISC和HOLD拥有数百万行的,但规则是相当小(< 1000行)。

我如何可以写一个本地的SQL任何建议,以实现这一目标? PL/SQL不是一个选项。

回答

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

这将返回MISC_ID = 2太 –

+0

没有也不会,它会比加入表本身(当然这取决于索引)相当快。 – cdhowie

+1

谢谢,你能解释一下“有分(READY)<> 0”吗? – user1550668

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 
+0

这并不在甲骨文工作。 – user1550668

+0

好的,你刚刚编辑了回应。 – user1550668

+0

@ user1550668:现在它工作吗? –

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 
相关问题