【问题标题】:Aggregate Query returning multiple records聚合查询返回多条记录
【发布时间】:2012-08-25 10:04:24
【问题描述】:

我有下表(简化):

RecordID       bigint         IDENTITY
ItemID         bigint
ConfigID       varchar
Status         varchar
StatusDate     date

样本数据

001  04  1E  10    2007-08-14 13:57:54
002  04  1E  12    2007-08-21 16:10:21
003  04  1D  10    2007-09-27 17:14:13
004  04  1D  43    2011-01-10 13:44:50
005  04  1B  50    2008-06-20 09:09:51
006  05  1A  17    2007-12-18 14:04:56
007  05  1A  11    2007-10-17 08:23:52
008  05  1A  12    2007-10-19 12:54:18
009  05  1B  12    2007-11-02 09:23:54
010  05  1B  40    2010-06-17 09:34:33
011  07  1A  12    2007-11-19 14:48:06
012  07  1A  12    2007-11-19 15:02:48
013  07  1B  40    2011-01-10 14:36:16
014  08  1B  10    2009-05-22 11:14:42
015  08  1B  12    2007-11-20 17:02:44
016  08  1A  12    2007-12-12 16:11:57
017  08  1A  10    2009-11-12 11:12:45
018  08  1C  35    2011-01-10 18:30:10
019  08  1D  12    2009-10-14 14:34:47
020  08  1D  10    2009-10-14 14:35:09

这就是我的问题:

我需要能够让最终用户查询此数据以返回记录,这些记录将显示 itemid 和 config 的每个唯一组合的最新状态和 statusdate。因此,使用上面的示例,我想返回一个匹配以下的记录集:

002  04  1E  12    2007-08-21 16:10:21
004  04  1D  43    2011-01-10 13:44:50
005  04  1B  50    2008-06-20 09:09:51
006  05  1A  17    2007-12-18 14:04:56
010  05  1B  40    2010-06-17 09:34:33
012  07  1A  12    2007-11-19 15:02:48
013  07  1B  40    2011-01-10 14:36:16
017  08  1A  10    2009-11-12 11:12:45
018  08  1C  35    2011-01-10 18:30:10
020  08  1D  10    2009-10-14 14:35:09

简而言之:我需要能够返回每个项目配置的最新状态和状态日期。

在这方面的任何帮助将不胜感激。提前谢谢你。

【问题讨论】:

    标签: sql tsql aggregation


    【解决方案1】:

    您可以在子查询中执行GROUP BY 子句。试试吧,

    SELECT  a.*
    FROM    yourtable a 
            INNER JOIN
            (
                SELECT      ItemID, ConfigID, MAX([StatusDate]) maxStat
                FROM        yourtable
                GROUP BY    ItemID,ConfigID
            ) b on a.configID = b.configID AND
                    a.[statusDate] = b.MaxStat AND
                    a.ItemID = b.ItemID
    Order by RecordID
    

    SQLFiddle Demo

    【讨论】:

    • 我认为有两个问题,他需要 itemID + configID 作为 groupBy 条件。如果你有两次相同的状态怎么办?然后他将获得该行两次而不是一次。示例二:04 1B 50、04 1B 50 日期不同。
    • 状态列应更改为 StatusDate 以获得最新的,而不是最大的“状态”
    • 很抱歉给您带来了困惑。我需要通过检查每个项目的配置的最大状态日期来返回每个项目的配置的记录(行)。这有意义吗?
    • @Bear 为什么014 08 1B 10 2009-05-22 11:14:42 未包含在您想要的结果中?是拼写错误吗?
    • 是的,它是......或者是一个测试,看看你是否在关注,是的,让我们开始吧。谢谢你的收获!
    【解决方案2】:

    在 SQL Server 2005+ 中,您可以使用 CTE:

    ;with cte as
    (
      select recordid,
        itemid,
        configid,
        status,
        statusdate,
        row_number() over(partition by itemid, configid
                            order by statusdate desc) rn
      from yourtable
    )
    select *
    from cte
    where rn = 1
    order by recordid
    

    SQL Fiddle with Demo

    【讨论】:

    • 这是一种享受!我得到了一些 minor 片状内含物,但它不仅仅基于此查询,它来自此处未列出的其他传入参数。我完全接受这个!
    • Bluefeet,我不得不回来再次感谢你的这个 sn-p!如果你曾经在北弗吉尼亚地区,请告诉我,午餐在我身上。
    • @Bear 如果任何答案有效,请务必接受它,以便未来的访问者知道答案。不需要午餐,我很乐意帮忙。 :)
    【解决方案3】:
    SELECT
        RecordID,
        ItemID,
        ConfigID,
        Status,
        StatusDate
    FROM
        (SELECT
            RecordID,
            ItemID,
            ConfigID,
            Status,
            StatusDate,
            ROW_NUMBER() OVER(PARTITION BY ItemId,ConfigID ORDER BY StatusDate DESC) As StatusOrder
        FROM
            MyTable) Statuses
    WHERE
        StatusOrder= 1
    

    【讨论】:

    • 我也喜欢这个答案。感谢您的宝贵时间!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多