【问题标题】:Cross joining sql tables by date按日期交叉连接 sql 表
【发布时间】:2015-08-02 09:33:32
【问题描述】:

我有一个下表,table1

date            value   
-------------------------
2015-01-01      0
2015-01-02      0
2015-01-03      0
2015-01-04      0

还有一张桌子2

datestart       dateend         value   
-------------------------------------
2015-01-02      2015-01-03      1

我想得到如下结果

date            value   
-------------------------
2015-01-01      0
2015-01-02      1
2015-01-03      1
2015-01-04      0

我尝试使用交叉应用

select table1.date, temp.value
from table1
cross join
(select table2.value from table2 where
table2.startdate <= table1.date and table2.enddate > table1.date) as temp

但我最终得到了

date            value   
-------------------------
2015-01-02      1
2015-01-03      1

我的代码有什么问题?

【问题讨论】:

    标签: sql sql-server sql-server-2008 tsql cross-join


    【解决方案1】:

    你可以像这样使用左连接:

    select table1.date, coalesce(table2.value,0) Value
    from table1
    left join table2
    on table1.date between table2.startdate and table2.enddate 
    order by 1
    

    虽然如果表 2 中有重叠的日期会变得一团糟。这可能不是你想要的,但如果你想对每个日期所属范围的所有值求和,你可以这样做:

    select table1.date, sum(coalesce(table2.value,0)) Value
    from table1
    left join table2
    on table1.date between table2.startdate and table2.enddate 
    group by table1.date
    

    否则你会在输出中得到重复的日期。

    【讨论】:

      【解决方案2】:

      您不需要交叉连接,但需要左连接:

      SELECT    table1.date, table2.value
      FROM      table1
      LEFT JOIN table2 ON table1.date BETWEEN table2.startdate AND table2.enddate
      

      【讨论】:

      • 运行你的代码后,我得到了和我一样的结果。我想从 table1 中获取所有日期(包含所有 365/366 天的统计表),但更改的值取决于 table2 中的值。
      【解决方案3】:

      LEFT JOIN 会在这里做:

      SELECT table1.date, table2.value
      FROM table1
      LEFT JOIN
      table2
      ON table2.startdate <= table1.date
      AND table2.enddate > table1.date
      

      【讨论】:

      • 此代码不返回表 2 中未提及的值为 0 的日期
      • @mko:你是对的。代替table2.value,使用COALESCE(table2.value, table1.value)
      【解决方案4】:

      试试这个查询。我已将列名 date 更改为 mydate。我猜 date 是一个关键字。

        select t1.mydate, (case when t2.value is null then 0 else t2.value end) as value from table1 t1 left join table2 t2 
          on t1.mydate between t2.datestart and t2.dateend order by mydate;
      

      这是小提琴: http://sqlfiddle.com/#!9/85265/1

      【讨论】:

      • 我使用了 coalesce(table2.value,0)
      猜你喜欢
      • 2017-03-26
      • 2019-03-03
      • 1970-01-01
      • 1970-01-01
      • 2022-01-14
      • 1970-01-01
      • 2021-12-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多