代码之家  ›  专栏  ›  技术社区  ›  Konzy262

如何在SQL中按多列分组和按日期排序?

  •  0
  • Konzy262  · 技术社区  · 6 年前

    我想在一个数据库表中排序结果,这样他们看起来像下面。。。

    ----------------------------------------------------------------------
    Id                                   | Day | Start Date | End Date   |
    ----------------------------------------------------------------------
    13D377E8-7674-4BE8-ACDF-472B634342D3 |  1  | 2019-11-26 | 2019-11-26 |
    13D377E8-7674-4BE8-ACDF-472B634342D3 |  2  | 2019-11-27 | 2019-11-27 | 
    13D377E8-7674-4BE8-ACDF-472B634342D3 |  3  | 2019-11-28 | 2019-11-28 |
    78C8F3AD-DE5B-48BD-849A-6E39C7EC6200 |  1  | 2019-11-27 | 2019-11-27 |
    78C8F3AD-DE5B-48BD-849A-6E39C7EC6200 |  2  | 2019-11-28 | 2019-11-28 |
    78C8F3AD-DE5B-48BD-849A-6E39C7EC6200 |  3  | 2019-11-29 | 2019-11-29 |
    B73ECD8B-5760-4F92-94E5-CF5270AEE36B |  1  | 2019-11-28 | 2019-11-28 |
    B73ECD8B-5760-4F92-94E5-CF5270AEE36B |  2  | 2019-11-29 | 2019-11-29 |
    B73ECD8B-5760-4F92-94E5-CF5270AEE36B |  3  | 2019-11-30 | 2019-11-30 |
    
    • 每组天数按ID分组
    • 需要在组内从最低到最高显示天数
    • 组需要按每个组中第一天的开始日期升序排列

    我试着做下面的事。。。

    SELECT Id, Day, Start Date, End Date
    FROM Table
    GROUP BY Id, Day, Start Date, End Date
    

    但可以预见的是,它的排序并不正确。从下面的图片中可以看到,由于具有最早的开始日期,应该首先出现的组出现在列表的后面。

    enter image description here

    我如何解决这个问题?

    我用下面的SQL尝试了下面的解决方案。。。

    SELECT Id, Day, StartDate, EndDate FROM AssessmentCentreStandardAssessmentAvailabilityScheduleItemSchedule
    WHERE AssessmentCentreStandardAssessmentAvailabilityScheduleItemId in 
    (SELECT Id FROM AssessmentCentreStandardAssessmentAvailabilityScheduleItem
    WHERE AssessmentCentreStandardAssessmentAvailabilityId = 
    (SELECT Id FROM AssessmentCentreStandardAssessmentAvailability WHERE AssessmentCentreId = 
    (SELECT Id FROM AssessmentCentre WHERE Name = 'Daily Assessment Centre')))
    ORDER BY
        MIN(StartDate) OVER(PARTITION BY Id),
        Id,
        Day,
        StartDate
    

    请注意,为了简洁起见,我没有在原始帖子中包含where子句。我不认为这会影响比赛结果,只是为了以防万一。

    这将返回以下。。。。

    enter image description here

    只是为了在不清楚的情况下直观地重申这些标准:

    enter image description here

    • 然后,我需要按每个组第一天的开始日期对整个组进行排序。会有重叠-所以组1中第2天的开始日期将与第2组中第1天的开始日期匹配,以此类推。
    1 回复  |  直到 5 年前
        1
  •  3
  •   GMB    6 年前

    要按最短开始日期排序,您可以创建一个窗口 min() order by 条款:

    SELECT Id, Day, Start_Date, End_Date
    FROM Table
    -- GROUP BY Id, Day, Start_Date, End_Date
    ORDER BY
        MIN(Start_Date) OVER(PARTITION BY Id),
        Id,
        Day,
        Start_Date,
        End_date
    

    SELECT 条款让我怀疑你实际上不需要 GROUP BY 条款。我对查询的这一部分进行了评论,如果出于某种我无法想象的原因,您确实需要它,请随意添加它(如果您只需要删除一些重复项,请使用 SELECT DISTINCT ,这使得意图更加清晰)。

    Demo on DB Fiddle :

    Id                                   | Day | Start_Date          | End_Date           
    :----------------------------------- | --: | :------------------ | :------------------
    13D377E8-7674-4BE8-ACDF-472B634342D3 |   1 | 26/11/2019 00:00:00 | 26/11/2019 00:00:00
    13D377E8-7674-4BE8-ACDF-472B634342D3 |   2 | 27/11/2019 00:00:00 | 27/11/2019 00:00:00
    13D377E8-7674-4BE8-ACDF-472B634342D3 |   3 | 28/11/2019 00:00:00 | 28/11/2019 00:00:00
    78C8F3AD-DE5B-48BD-849A-6E39C7EC6200 |   1 | 27/11/2019 00:00:00 | 27/11/2019 00:00:00
    78C8F3AD-DE5B-48BD-849A-6E39C7EC6200 |   2 | 28/11/2019 00:00:00 | 28/11/2019 00:00:00
    78C8F3AD-DE5B-48BD-849A-6E39C7EC6200 |   3 | 29/11/2019 00:00:00 | 29/11/2019 00:00:00
    B73ECD8B-5760-4F92-94E5-CF5270AEE36B |   1 | 28/11/2019 00:00:00 | 28/11/2019 00:00:00
    B73ECD8B-5760-4F92-94E5-CF5270AEE36B |   2 | 29/11/2019 00:00:00 | 29/11/2019 00:00:00
    B73ECD8B-5760-4F92-94E5-CF5270AEE36B |   3 | 30/11/2019 00:00:00 | 30/11/2019 00:00:00