簡體   English   中英

從表中選擇滿足子表中所有在另一表中至少有一條記錄的所有行的條件的行

[英]Select rows from a table satisfying criteria for all rows in a child table which have at least one record in another table

我們有帶有process_id主鍵的表“ PROCESS”。 進程具有“項”,這些項以(process_id,item_id)作為主鍵存儲在另一個表“ ITEM”中。 每個項目都有“事件”,這些事件存儲在另一個表“ EVENT”中,該表以(process_id,item_id,event_id)作為主鍵。 事件具有類型(存儲在“ events”。“ event_type”列中)我們假設存在類型為“ A”的事件。

我想選擇所有項目中至少有一個類型為“ A”的事件的流程(因此,如果一個項目沒有此類事件,則結果集中不需要此類流程)。

我最終得到以下查詢:

SELECT needed_processes.process_id FROM (
SELECT items.process_id, items.number_of_items, events.number_of_events    FROM 
(SELECT process.process_id, count(*) number_of_items FROM process
  JOIN item ON process.process_id = item.process_id 
  GROUP BY process.process_id
) items JOIN 
(SELECT needed_events.process_id, count(*) number_of_events FROM 
  (SELECT process.process_id, item.item_id FROM process JOIN item
    ON process.process_id = item.process_id JOIN events ON item.process_id = event.process_id 
    AND item.item_id = event.item_id
    WHERE event.event_type = 'A' 
    group by process.process_id, item.item_id
  ) needed_events group by needed_events.process_id
) events ON items.process_id = events.process_id
where items.number_of_items = events.number_of_events) needed_processes

它計算一個流程的項目數,並檢查該流程所需的事件數等於它的項目數。

該查詢難以閱讀,難以理解,而且看起來並不高效。

是否有針對此任務的更簡單查詢(就閱讀或性能而言)?

我可以使用特定於oracle的查詢,也歡迎使用與數據庫無關的查詢。

例子

處理

|process_id|
|1         |
|2         |
|3         |
|4         |

項目(項目始終僅屬於一個過程)

|process_id|item_id|
|1         |11     |
|1         |12     |
|1         |13     |
|2         |14     |
|2         |15     |
|3         |16     |

事件(事件始終僅屬於一項)

|process_id|item_id|event_id|event_type|
|1         |11     |21      |A         |
|1         |11     |22      |A         |
|1         |11     |23      |B         |
|1         |13     |24      |A         |
|2         |14     |25      |A         |
|2         |14     |26      |A         |
|2         |15     |27      |A         |
|2         |15     |28      |B         |

結果

|process_id|
|2         |

process_id = 1應該被過濾掉,因為它沒有項目12的類型A的事件。它有兩個項目11的類型A的事件,但是應將它們視為“項目11有事件A”。 應在結果集中返回process_id = 2,因為其所有項目的事件類型均為A。 對於項目14,它具有兩個類型為A的事件,並且這不會影響結果。 process_id = 3不應該返回,因為它沒有任何事件(=>每個項目都不具有類型A的事件)process_id = 4不應該返回,因為它沒有任何事件(拐角情況) )。

這將返回所有事件,其中每個項目都有一個事件“ A”的所有過程:

select process_id
from events
group by process_id
having count(distinct item_id)                                     -- all items
     = count(distinct case when event_type = 'A' then item_id end) -- only items with event 'A'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM