【问题标题】:Selecting DISTINCT records on subset of columns with MAX in another column在另一列中选择具有 MAX 的列子集上的 DISTINCT 记录
【发布时间】:2011-05-13 11:10:01
【问题描述】:

我已经在网站上查看了其他 T-SQL 问题,包括 DISTINCT 和 MAX 几个小时,但找不到完全符合我需要的任何内容。这是我的数据集和查询目标的描述。非常感谢任何指导。

数据集 数据集是上一个计费周期的客户、客户地点、日期和值的列表,包含以下列。一个客户可以拥有多个网站:

客户、站点、日期、计数器、CounterValue、CollectorNode

查询要求 对于给定的计费周期,我想选择以下

  • DISTINCT(客户和网站)
  • 每个 DISTINCT 客户和站点的此计费周期的 MAX(CounterValue)
  • 仍然从表中返回该记录的所有字段(CollectorNode、Date、Counter)

我的挑战是我无法在选择 DISTINCT 列和每个列的 MAX 时返回所有列。我的许多不同尝试为每个客户/站点组合返回多个记录。

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案1】:

    使用子查询进行分组并将结果连接回原始表,如下所示:

    SELECT g.Customer, g.Site, c.Date, c.Counter, g.MaxCounterValue, c.CollectorNode
    FROM Customers c
    INNER JOIN
    (
    SELECT Customer, Site, MAX(CounterValue) MaxCounterValue
    FROM Customers
    GROUP BY Customer, Site
    ) g
    ON g.Customer = c.Customer
    AND g.Site = g.Site
    

    【讨论】:

      【解决方案2】:

      使用自联接:

      SELECT ds.customer,
             ds.site,
             ds.counter, 
             ds.countervalue,
             ds.collectornode
        FROM DATASET ds
        JOIN (SELECT t.customer,
                     t.site,
                     MAX(t.countervalue) AS max_countervalue
                FROM DATASET t
            GROUP BY t.customer, t.site) x ON x.customer = ds.customer
                                          AND x.site = ds.site
                                          AND x.max_countervalue = ds.countervalue
      

      使用 CTE 和 ROW_NUMBER (SQL Server 2005+):

      WITH example AS (
         SELECT ds.customer,
                ds.site,
                ds.counter, 
                ds.countervalue,
                ds.collectornode,
                ROW_NUMBER() OVER(PARTITION BY ds.customer, ds.site
                                      ORDER BY ds.countervalue DESC) AS rank
           FROM DATASET ds)
      SELECT e.customer,
             e.site,
             e.counter, 
             e.countervalue,
             e.collectornode
        FROM example e
       WHERE e.rank = 1
      

      【讨论】:

      • 如何将 WHERE 子句合并到“Self JOIN”示例中。虽然我想报告当前的结算月份,但我们有几个月的数据,需要将记录集过滤为我们选择的目标日期范围(开始和结束日期)的记录集。
      • @PJZ:在自连接中,最安全的方法是在ds 和包含x 的派生表查询的括号内指定WHERE 条件。仅将 WHERE 应用于一个可能会使另一个不具有相同的值。
      • 我明白你的意思。星期一去处理这个问题,看看我是否可以根据你的建议解决这个问题。谢谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-03
      • 2023-03-14
      • 2016-01-12
      • 1970-01-01
      • 2012-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多