【问题标题】:Merge data from three or more identical columns of different tables into single column将来自不同表的三个或更多相同列的数据合并到单个列中
【发布时间】:2016-07-08 16:04:48
【问题描述】:

我有三个不同的表,月份和项目如下: 表1

month books
April-2016  2
February-2016   7
January-2016    1
June-2016   6
May-2016    1
September-2015  1

表2

month copies
April-2016  92
August-2015 1
February-2016   49
January-2016    5
June-2016   127

表3

month pens
February-2016   74
January-2016    1
June-2016   66
March-2016  136
May-2016    128

现在,我看起来像这样: 月书副本笔 - 月份列应合并,其他数据应放在相应列中(如果没有可用数据,则应放置 0),例如

month books copies pens
April-2016  2 92 0
September-2015  1 0 0
August-2015 0 1 0
June-2016   6 127 66

我试过了

select COALESCE(t1.Month,t2.Month,t3.Month) AS [Month],
ISNULL(t1.books,0) AS books,
ISNULL(tp.copies,0) AS copies,
ISNULL(tn.pens,0) AS pens
from  #table1 t1
full join #table t2 on t1.month=t2.month
full join #table t3 on t1.month=t3.month

---Union 不起作用,因为它给了我 6 列(3 个月,我只需要 1)

【问题讨论】:

  • 您的查询有什么问题?
  • 您的查询正在从同一个表中提取数据 3 次。我不认为那是你的意思。老实说,您在获取数据时遇到此类问题的原因是您的设计存在缺陷。您不应该为每种类型的项目都有一个表格。您应该有一列表明它是哪种类型的项目。
  • @Sean Lange - 我希望目的是将结果插入新表中......
  • 是的,它不是从 3 个临时表中的各个表中提取的数据,以便在报告中如此(这里与表设计无关......)
  • 您的设计使这变得困难。如果您有更好的设计,查询会很简单。

标签: sql sql-server join union coalesce


【解决方案1】:

我知道的最佳方法是将月份提取为工作表,然后依次左连接每个源表以一一获取列。如果您知道每个表中有相同的月份列表,则无需提取月份。

select a.month,
       t1.books,
       t2.copies,
       t3.pens
  from (
select month from table1
union
select month from table2
union
select month from table3) a
left join table1 t1
    on a.month = t1.month
left join table2 t2
    on a.month = t2.month
left join table3 t3
    on a.month = t3.month

【讨论】:

    【解决方案2】:

    您可以使用full join 执行此操作。它看起来像这样:

    select COALESCE(t1.Month,t2.Month,t3.Month) AS [Month],
           COALESCE(t1.books,0) AS books,
           COALESCE(t2.copies,0) AS copies,
           COALESCE(t3.pens,0) AS pens
    from  #table1 t1 full join
          #table t2
          on t2.month = t1.month full join
          #table t3
          on t3.month = coalesce(t1.month, t2.month);
    

    就个人而言,我发现union all/group by 方法也许是最直观的:

    select month,
           sum(books) as books, sum(copies) as copies, sum(pens) as pens
    from ((select month, books, 0 as copies, 0 as pens from #table1
          ) union all
          (select month, 0 as books, copies, 0 as pens from #table2
          ) union all
          (select month, 0 as books, 0 as copies, pens from #table3
          )
         ) bcp
    group by month;
    

    Mike 建议的left join 方法也很合理;通常,我宁愿不必在两个地方列出每个表。如果我稍后更新查询,这可能会导致错误。

    【讨论】:

    • Mike Christie 和 Gordon Linoff:感谢这两种方法都解决了......但是,你能告诉我查询优化的最佳选择是什么(我的意思是,就查询运行时间而言...... )
    • @LearnByExample 。 . .为了提高性能,您应该使用合理大小的数据在系统上测试这两个查询。在某些情况下,任一版本的性能都会更好。
    猜你喜欢
    • 2013-10-10
    • 2016-12-09
    • 1970-01-01
    • 1970-01-01
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-28
    相关资源
    最近更新 更多