2012-11-16 43 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 
相關問題