【问题标题】:Combine output of two queries without using union or temporary table在不使用联合表或临时表的情况下合并两个查询的输出
【发布时间】:2021-05-27 10:46:05
【问题描述】:

我有下表 IDValues

ID Unique ID Sort Order Start Date End Date Changed Value
501 23 2 2011-01-14 2011-12-19 0 664
302 15 9 2021-03-05 2021-04-27 0 223
351 31 6 2017-08-18 2017-10-16 0 765
501 27 3 2011-12-20 2012-01-15 1 416
501 19 1 2010-12-29 2011-01-03 0 519
351 26 3 2016-01-19 2016-03-11 0 364
501 21 4 2012-01-16 2012-05-15 1 447
302 14 10 2021-04-28 2021-05-15 1 776
413 41 5 2018-08-20 2018-12-11 0 679
455 41 7 2017-11-23 2018-01-25 1 456

我需要找到 Changed=1 和 Sort Order=x 的 ID 及其详细信息,以及 Sort Order=x-1 的 ID,即具有先前排序顺序的 ID(如果存在)。

对于排序顺序 = x 的 ID,我必须找到天数 = 从 StartDate 到月底的天数 对于排序顺序 = x-1 的 ID,我必须找到天数 = 从月初到 EndDate 的天数。

我尝试分两部分进行,并使用临时表并结合两个结果。

Select *, DATEDIFF(d,StartDate,eomonth(StartDate)) as NoOfDays
into #temptbl
from IDDetails where Changed=1

Select A.*, day(EndDate) as NoOfDays from IDDetails A inner join #temptbl B
on A.ID=B.ID and A.SortOrder= B.SortOrder-1

当我结合这些结果时,我得到了想要的输出。但我不想使用临时表或联合函数。下面是我需要的输出。有没有其他方法可以在不编写两个查询的情况下获得输出?

输出:

ID Unique ID Sort Order Start Date End Date Changed Value No. of days
501 23 2 2011-01-14 2011-12-19 0 664 19
302 15 9 2021-03-05 2021-04-27 0 223 27
501 27 3 2011-12-20 2012-01-15 1 416 12
501 21 4 2012-01-16 2012-05-15 1 447 16
302 14 10 2021-04-28 2021-05-15 1 776 3
501 27 3 2011-12-20 2012-01-15 1 416 15
455 41 7 2017-11-23 2018-01-25 1 456 25

【问题讨论】:

  • 您使用的是MySQL 还是SQL-Server
  • @apanda 。 . .根据查询的语法,我假设您使用的是 SQL Server,所以我删除了 MySQL 标记。
  • 您可以使用 CTE 而不是临时表。另外,为什么不使用临时表?
  • @MarkoIvkovic 我正在使用 SQL-Server。我的错误是我添加了 MySQL 标签。

标签: sql sql-server


【解决方案1】:

最直接的选择就是使用嵌套查询。获取您的第一个查询并将其嵌套在您的第二个查询中...

Select
  A.*, day(EndDate) as NoOfDays
from
  IDDetails A
inner join
(
  Select
    *,
    DATEDIFF(d,StartDate,eomonth(StartDate)) as NoOfDays
  from
    IDDetails
  where
    Changed = 1
)
  B
    on  A.ID        = B.ID
    and A.SortOrder = B.SortOrder - 1

这本身可以进一步简化为简单的自连接...

SELECT
  A.*, day(EndDate) as NoOfDays
FROM
  IDDetails A
INNER JOIN
  IDDetails B
    on  A.ID        = B.ID
    and A.SortOrder = B.SortOrder - 1
WHERE
  B.Changed = 1

注意事项:

  • day(EndDate) 在所有情况下都是模棱两可的; AB 都有一个 EndDate,指定 A.EndDateB.EndDate
  • 您在B 中创建 NoOfDays 列,然后不要在第二个查询中使用它

【讨论】:

    【解决方案2】:

    如果您不想使用临时表,也许您想使用通用表达式表 (CTE),对于这种目的来说,这是一种很好且可读的方式

    所以这段代码:

    Select *, DATEDIFF(d,StartDate,eomonth(StartDate)) as NoOfDays
    into #temptbl
    from IDDetails where Changed=1
    
    Select A.*, day(EndDate) as NoOfDays from IDDetails A inner join #temptbl B
    on A.ID=B.ID and A.SortOrder= B.SortOrder-1
    

    变成这样:

    With _Changed1 AS (
        SELECT *, DATEDIFF(d,StartDate,eomonth(StartDate)) AS NoOfDays
        FROM IDDetails 
        WHERE Changed=1
    )
    SELECT A.*, day(EndDate) AS NoOfDays 
    FROM IDDetails A 
    INNER JOIN _Changed1 B
    ON A.ID=B.ID 
    AND A.SortOrder= B.SortOrder-1
    

    【讨论】:

      【解决方案3】:

      通过代码连接两个选择结果,例如将它们合并到一个数组中。

      【讨论】:

        猜你喜欢
        • 2023-04-06
        • 2012-11-27
        • 2018-06-21
        • 1970-01-01
        • 2021-11-12
        • 1970-01-01
        • 1970-01-01
        • 2011-12-21
        • 1970-01-01
        相关资源
        最近更新 更多