【问题标题】:Grabbing only one ( newest ) detail record from child table for multiple parent Id's in one query在一个查询中仅从子表中获取多个父 ID 的一个(最新)详细记录
【发布时间】:2018-03-05 15:39:11
【问题描述】:

我对一个查询有疑问,老实说,我不知道这是否可以以良好且可读的方式编写。

我有 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# 代码中的解决方案。拳头,我为每个事件获取所有 DETAILS_ID,然后调用另一个 SQL 获取此 ID 的所有详细信息,并使用 LINQ garbing latest 对其进行排序。从技术上讲,这项工作很慢。

所以我的问题是我是否可以有一个 SQL 语句来获取我传递的每个 EVENT_ID 的最新说明(每个 EVENT_ID 的 EVENT_TYPE 和 DETAIL_TYPE 将是相同的)?

所以对于像这样的数据:

活动:

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

谢谢。

【问题讨论】:

  • 我只是想明白,你有多个事件。每个 EVENT 可以有多个 EVENT_DETAILS。您想传递一个查询来获取事件的最新 EVENT_DETAILS?
  • 我想通过一个查询来获取每个事件的最新(按时间排序)EVENT_DETAIL。我将按问题进行编辑以解释这一点。
  • 问题很好,我错过了输入我的问题。我编辑了它,但您没有及时看到它抱歉。
  • 为什么EVENT_DETAIL 没有EVENT_ID?我无法遵循数据结构。样本数据和期望的结果会有所帮助。
  • 我用示例数据编辑了我的问题。

标签: c# sql oracle


【解决方案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 

【讨论】:

  • 我认为这行不通,因为我认为DETAIL_IDEVENT_DETAIL 的每一行中都是唯一的。很难说,因为数据结构相当神秘,但这是我最好的猜测。
【解决方案2】:

如果我对问题的理解正确,您可以使用窗口函数来获取事件的每种类型的最新详细信息:

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;

【讨论】:

    【解决方案3】:

    我会为此使用一个窗口函数。希望这可以帮助。谢谢。

    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
    

    【讨论】:

      猜你喜欢
      • 2020-11-24
      • 2022-11-27
      • 1970-01-01
      • 1970-01-01
      • 2021-01-10
      • 2018-01-14
      • 2013-05-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多