【问题标题】:Combine rows when the end time of one is the start time of another, if not then as it is in SQL当一个的结束时间是另一个的开始时间时合并行,如果不是,那么就像在 SQL 中一样
【发布时间】:2018-09-20 04:55:25
【问题描述】:

当一个的结束时间是另一个的开始时间时合并行,如果不是,那么就像在 SQL 中一样。 例如:

DATE_SRNO   start                   End                       Actual_Date
1          2018-08-04 12:22:00.000  2018-08-04 13:22:00.000   2018-08-04
1          2018-08-04 13:22:00.000  2018-08-04 16:46:00.000   2018-08-04
1          2018-08-04 20:17:00.000  2018-08-04 21:16:00.000   2018-08-04
1          2018-08-04 22:12:00.000  2018-08-04 22:28:00.000   2018-08-04
2          2018-08-05 19:08:00.000  2018-08-05 20:00:00.000   2018-08-05
2          2018-08-05 20:00:00.000  2018-08-05 20:52:00.000   2018-08-05
3          2018-08-20 07:27:00.000  2018-08-21 06:00:00.000   2018-08-20
3          2018-08-21 03:36:00.000  2018-08-21 04:36:00.000   2018-08-20
3          2018-08-21 04:36:00.000  2018-08-21 06:00:00.000   2018-08-20

预期输出:

Sr.No   start                    End                        Actual_Date
1       2018-08-04 12:22:00.000 2018-08-04 16:46:00.000     2018-08-04
1       2018-08-04 20:17:00.000 2018-08-04 21:16:00.000     2018-08-04
1       2018-08-04 22:12:00.000 2018-08-04 22:28:00.000     2018-08-04
2       2018-08-05 19:08:00.000 2018-08-05 20:52:00.000     2018-08-05
3       2018-08-20 07:27:00.000 2018-08-21 06:00:00.000     2018-08-20
3       2018-08-21 03:36:00.000 2018-08-21 06:00:00.000     2018-08-20

我尝试了以下查询,但没有得到确切的输出。

SELECT
    T1.Malf_start,
    T2.MalfEnd,
    T1.COMPARE_DATE
FROM
    #temp T1
INNER JOIN
    #temp T2
    ON T2.DATE_SRNO = T1.DATE_SRNO
    AND T2.Malf_start = T1.MalfEnd

下面是我得到的结果。

start                   End                     Actual_Date
2018-08-04 12:22:00.000 2018-08-04 16:46:00.000 2018-08-04
2018-08-05 19:08:00.000 2018-08-05 20:52:00.000 2018-08-05
2018-08-21 03:36:00.000 2018-08-21 06:00:00.000 2018-08-20

【问题讨论】:

  • 如果不是,那么就像在 SQL 中一样?这是什么意思?
  • 告诉我们正在使用哪个数据库。 “SQL”本身并不能告诉我们为您的问题选择正确的语法。顺便说一下,“SQL”并不意味着“SQL Server”。
  • 这是 SQL Server 2017

标签: sql sql-server sql-server-2017


【解决方案1】:
SELECT
    t1.malf_start,
    COALESCE(t2.malf_end, t1.malf_end) AS malf_end,
    t1.actual_date
FROM
    test_date t1
LEFT JOIN
    test_date t2
    ON t1.actual_date = t2.actual_date
    AND t1.malf_end = t2.malf_start
LEFT JOIN
    test_date t3
    ON t1.actual_date = t3.actual_date
    AND t1.malf_start = t3.malf_end
WHERE t3.malf_start IS NULL

解释:

  • T1 是所有记录的列表。
  • T2 是开始日期与 T1 中的结束日期匹配的记录。
  • 如果没有 T2 匹配,我们将显示原始 T1 结束日期。
  • T3 用于检查 T2 中是否使用了任何 T1 记录。我们不想显示已附加到 T1 记录的记录。

【讨论】:

  • 我希望第一行的开始日期是 2018-08-04 12:22:00.000,结束日期是 2018-08-04 16:46:00.000。根据您的查询,其演出开始日期为 2018-08-04 13:22:00.000,结束日期为 2018-08-04 16:46:00.000
  • 交换了 LEFT JOIN 的左右两边。请检查结果。
  • 我之前的评论不是很清楚。我的意思是 SQL 中有错误。它已被修复,结果现在符合您的要求
【解决方案2】:

您需要定义合并的所有行。执行此操作的一种方法是将组分配给行并确定新组的开始位置。那么:

  • 定义组的开始的累积总和
  • 按组聚合

这看起来像:

select date_srno,
       min(malfstart), max(malfend)
from (select t.*,
             sum(case prev_malfend = malfstart then 0 else 1 end) over (partition by date_srno order by malfstart) as grp
      from (select t.*,
                   lag(t.malfend) over (partition by t.date_srno order by t.mslfstart) as prev_malfend
            from #temp t
           ) t
     ) t
group by date_srno, grp;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-25
    • 1970-01-01
    • 1970-01-01
    • 2019-07-15
    • 2021-01-19
    • 2012-04-29
    • 2019-10-31
    • 2016-02-03
    相关资源
    最近更新 更多