【问题标题】:Max and Min value's corresponding records最大值和最小值的对应记录
【发布时间】:2016-11-11 05:31:24
【问题描述】:

我有一个场景来获取“Max”和“Min”记录的相应字段值 请在下面找到示例数据

-----------------------------------------------------------------------
ID             Label             ProcessedDate
-----------------------------------------------------------------------
1              Label1            11/01/2016
2              Label2            11/02/2016
3              Label3            11/03/2016
4              Label4            11/04/2016
5              Label5            11/05/2016

我在另一个表中填充了“ID”字段作为外键。在根据“ID”字段查询该表中的这些记录时,我需要获取“最大”处理日期和“最小”处理日期的“标签”字段。

 -----------------------------------------------------------------------
    ID      LabelID      GroupingField
 -----------------------------------------------------------------------
    1       1            101
    2       2            101
    3       3            101
    4       4            101
    5       5            101
    6       1            102
    7       2            102
    8       3            102
    9       4            102

我希望最终结果集看起来像这样。

 -----------------------------------------------------------------------
   GroupingField         FirstProcessed         LastProcessed
 -----------------------------------------------------------------------
   101                   Label1                 Label5
   102                   Label1                 Label4

我已经“几乎”设法使用 rank 函数获得了上述结果,但仍然不满意。所以我正在寻找是否有人可以为我提供更好的选择。

谢谢, 普拉卡兹

【问题讨论】:

    标签: sql sql-server rank


    【解决方案1】:
        CREATE TABLE #Details (ID INT,LabelID INT,GroupingField INT)
    CREATE TABLE #Details1 (ID INT,Label VARCHAR(100),ProcessedDate VARCHAR(100)) 
    
    INSERT INTO #Details1 (ID ,Label ,ProcessedDate )
    SELECT 1,'Label1','11/01/2016' UNION ALL
    SELECT 2,'Label2','11/02/2016' UNION ALL
    SELECT 3,'Label3','11/03/2016' UNION ALL
    SELECT 4,'Label4','11/04/2016' UNION ALL
    SELECT 5,'Label5','11/05/2016'
    
    
    INSERT INTO #Details (ID ,LabelID ,GroupingField )
    SELECT 1,1,101 UNION ALL
    SELECT 2,2,101 UNION ALL
    SELECT 3,3,101 UNION ALL
    SELECT 4,4,101 UNION ALL
    SELECT 5,5,101 UNION ALL
    SELECT 6,1,102 UNION ALL 
    SELECT 7,2,102 UNION ALL
    SELECT 8,3,102 UNION ALL
    SELECT 9,4,102
    
    ;WITH CTE (GroupingField , MAXId ,MinId) AS
    (
        SELECT GroupingField,MAX(LabelID) MAXId,MIN(LabelID) MinId
        FROM #Details
        GROUP BY GroupingField  
    )
    
    
    SELECT GroupingField ,B.Label FirstProcessed, A.Label LastProcessed
    FROM CTE
    JOIN #Details1 A ON MAXId = A.ID
    JOIN #Details1 B ON MinId = B.ID
    

    【讨论】:

      【解决方案2】:

      您可以使用 SQL Row_Number() 函数使用 Partition By,如下所示与 Group By 的组合

      ;with cte as (
          select 
              t.Label, t.ProcessedDate,
              g.GroupingField,
              ROW_NUMBER() over (partition by GroupingField Order By ProcessedDate ASC) minD,
              ROW_NUMBER() over (partition by GroupingField Order By ProcessedDate DESC) maxD
      
          from tbl t 
          inner join GroupingFieldTbl g
          on t.ID = g.LabelID
       )
      select GroupingField, max(FirstProcessed) FirstProcessed, max(LastProcessed) LastProcessed
      from (
      select
           GroupingField,
           FirstProcessed = CASE when minD = 1 then Label else null end,
           LastProcessed = CASE when maxD = 1 then Label else null end
      from cte 
      where 
          minD = 1 or  maxD = 1
      ) t
      group by GroupingField
      order by GroupingField
      

      我还使用 CTE 表达式使编码更容易理解

      输出如下

      【讨论】:

      • 是的,这对我来说很好!我几乎有同样的事情,唯一缺少的是我没有使用 CTE 和一个额外的分组层与 groupingID。无论如何谢谢你!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 2019-03-18
      • 2020-11-19
      • 2014-12-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多