在一个查询{G <44}中仅从子表中抓取多个父ID的一条(最新)详细记录

时间:2018-03-05 15:39:12

标签: c# sql oracle

我有一个查询的问题,说实话我不知道这是否有可能以良好和可读的方式编写。

我有2张桌子。

首先是包含4列的事件:

EVENT_ID | EVENT_TYPE | DETAIL_TYPE | DETAIL_ID

第二个表是EVENT_DETAIL,列数超过10列,但我们只需要其中的3个:

DETAIL_ID | ..... | TIME | DESCRIPTION.

在当前场景中,我们将事件存储在EVENT表中。每个事件都可以包含多种类型的多个详细信息。

我需要做的是获取最新EVENT_DETAIL.TIME的EVENT_ID的描述说明

我创建了这个SQL,也许它看起来并不好看,但至少它起作用了:

SELECT * FROM EVENT_DETAIL ED
WHERE ED.DESCRIPTION IN
(SELECT * FROM
( SELECT ED.DESCRIPTION
FROM EVENT_DETAIL ED
JOIN EVENT E ON ED.DETAIL_ID = E.DETAIL_ID AND 
E.EVENT_ID = 10 AND E.EVENT_TYPE  = 1 AND  E.DETAIL_TYPE = 1
WHERE ROWNUM = 1
ORDER BY ED.TIME DESC)); 

问题在于SQL我只能传递一个EVENT_ID(我知道我可以多次加入它但我不认为这会是个好主意)我需要运行这个查询例如十个EVENT(EVENT_TYPE和DETAIL_TYPE将在整个时间内相同)。

在目前的产品中,我有C#代码的解决方案。 Fist I获取每个EVENT的所有DETAILS_ID,然后调用另一个SQL来获取此ID的所有详细信息,并使用最新的LINQ加密对其进行排序。从技术上讲,这项工作非常缓慢。

所以我的问题是我是否可以使用一个SQL语句来获取我传递的每个EVENT_ID的最新描述(EVENT_TYPE和DETAIL_TYPE对于每个EVENT_ID都相同)?

因此对于以下数据:

活动:

10    |    1    |    1    |    1
10    |    1    |    1    |    2
10    |    1    |    1    |    3
11    |    1    |    1    |    5
11    |    1    |    1    |    6
11    |    1    |    1    |    7

EVENT_DETAIL:

1     |    12-12-2013    |    TEST1    
2     |    12-13-2013    |    TEST2    
3     |    12-14-2013    |    TEST3      
5     |    12-13-2013    |    TEST4    
6     |    12-14-2013    |    TEST5   
7     |    12-15-2013    |    TEST6     

参数EVENT_ID in (10,11) , EVENT_TYPE = 1 , DETAIL_TYPE = 1

我希望得到如下结果:

3    |    TEST3
7    |    TEST6

感谢。

3 个答案:

答案 0 :(得分:1)

您可以通过detail_id

使用max(ed.time)组的连接
select * from 
FROM EVENT_DETAIL ED 
inner join (
      select ED.DETAIL_ID,   max(ED.TIME) max_time
      FROM EVENT_DETAIL ED
      JOIN EVENT E ON ED.DETAIL_ID = E.DETAIL_ID 
      group by ED.DESCRIPTION 
) T.DETAIL_ID = ED.DETAIL_ID  AND ED.TIME = T.max_time 

答案 1 :(得分:0)

如果我正确理解了这个问题,你可以使用窗口函数来获取事件的每种类型的最新细节:

SELECT *
FROM (SELECT ED.*,
             ROW_NUMBER() OVER (PARTITION BY E.EVENT_ID, E.DETAIL_TYPE ORDER BY ED.TIME DESC) as seqnum
      FROM EVENT_DETAIL ED JOIN
           EVENT E
           ON ED.DETAIL_ID = E.DETAIL_ID
     ) ED
WHERE seqnum = 1;

答案 2 :(得分:0)

我会为此目的使用窗口函数。希望这可以帮助。感谢。

select EVENT_ID, 
       DESCRIPTION
from (  
    select E.EVENT_ID, 
           ED.DESCRIPTION,
           row_number() over (partition by DETAIL_ID order by TIME desc) as rnum
    from EVENT E
    join EVENT_DETAIL ED 
    on (ED.DETAIL_ID = E.DETAIL_ID)) t
where t.rnum = 1