3

更新:

我最初使用 FULL OUTER JOIN 的尝试没有正常工作。我已经更新了问题以反映真正的问题。很抱歉提出了一个经典的XY 问题


我正在尝试在一个查询中从多个表中检索数据集,该查询按数据的年、月分组。

最终结果应如下所示:

| 年份 | 月 | Col1 | Col2 | Col3 |
|------+-------+------+------+------|
| 2012 | 11 | 231 | - | - |
| 2012 | 12 | 第534章 12 | 13 |
| 2013 | 1 | - | 22 | 14 |

来自如下所示的数据:

表格1:

| 年份 | 月 | 数据 |
|------+--------+------|
| 2012 | 11 | 231 |
| 2012 | 12 | 第534章

表 2:

| 年份 | 月 | 数据 |
|------+--------+------|
| 2012 | 12 | 12 |
| 2013 | 1 | 22 |

表3:

| 年份 | 月 | 数据 |
|------+--------+------|
| 2012 | 12 | 13 |
| 2013 | 1 | 14 |

我尝试使用FULL OUTER JOIN,但这并不完全有效,因为在我的SELECT子句中,因为无论我从哪个表中选择“年”和“月”,都有空值。

SELECT 
 Collase(t1.year,t2.year,t3.year)
,Collese(t1.month,t2.month,t3.month)
,t1.data as col1
,t2.data as col2
,t3.data as col3
From t1
FULL OUTER JOIN t2
on t1.year = t2.year and t1.month = t2.month
FULL OUTER JOIN t3
on t1.year = t3.year and t1.month = t3.month

结果是这样的(太混乱了,无法准确重复我使用此演示数据会得到的结果):

| 年份 | 月 | Col1 | Col2 | Col3 |
|------+-------+------+------+------|
| 2012 | 11 | 231 | - | - |
| 2012 | 12 | 第534章 12 | 13 |
| 2013 | 1 | - | 22 | |
| - | 1 | - | - | 14 |
4

6 回答 6

2

如果您的数据允许(不是 100 列),这通常是一种干净的方法:

select year, month, sum(col1) as col1, sum(col2) as col2, sum(col3) as col3
from (
    SELECT t1.year, t1.month, t1.data as col1, 0 as col2, 0 as col3
    From t1
    union all 
    SELECT t2.year, t2.month, 0 as col1, t2.data as col2, 0 as col3
    From t2
    union all 
    SELECT t3.year, t3.month, 0 as col1, 0 as col2, t3.data as col3
    From t3
) as data
group by year, month
于 2012-12-04T20:45:15.237 回答
1

您可以从所有表中导出完整的年月列表,而不是将每个表连接到该列表(使用左连接):

SELECT 
  f.Year,
  f.Month,
  t1.data AS col1,
  t2.data AS col2,
  t3.data AS col3
FROM (
  SELECT Year, Month FROM t1
  UNION
  SELECT Year, Month FROM t2
  UNION
  SELECT Year, Month FROM t3
) f
LEFT JOIN t1 ON f.year = t1.year and f.month = t1.month
LEFT JOIN t2 ON f.year = t2.year and f.month = t2.month
LEFT JOIN t3 ON f.year = t3.year and f.month = t3.month
;

您可以在 SQL Fiddle看到此查询的现场演示。

于 2012-12-04T22:36:29.720 回答
1

也许您正在寻找COALESCE关键字?它接受一个列列表并返回第一个不是 NULL 的列,如果所有参数都为空,则返回 NULL。在你的例子中,你会做这样的事情。

SELECT COALESCE(t1.data, t2.data)

在这种情况下,您仍然需要连接表。它只会减少案例陈述。

于 2012-12-04T20:47:42.940 回答
1

如果您使用的是 SQL Server 2005 或更高版本,您还可以尝试以下 PIVOT 解决方案:

SELECT 
  Year,
  Month,
  Col1,
  Col2,
  Col3
FROM (
  SELECT Year, Month, 'Col1' AS Col, Data FROM t1
  UNION ALL
  SELECT Year, Month, 'Col2' AS Col, Data FROM t2
  UNION ALL
  SELECT Year, Month, 'Col3' AS Col, Data FROM t3
) f
PIVOT (
  SUM(Data) FOR Col IN (Col1, Col2, Col3)
) p
;

可以在 SQL Fiddle测试和使用此查询。

于 2012-12-04T22:43:10.980 回答
0

如果您要从任一 tabloe 中查找非空值,那么您也必须添加 t1.dat IS NOT NULL。我希望我能理解你的问题。

CREATE VIEW joined_SALES
AS SELECT t1.year, t1.month, t1.data , t2.data 
FROM table1 t1, table2 t2
WHERE
    t1.year = t2.year 
    and    t1.month = t2.month
    and    t1.dat IS NOT NULL
GROUP BY t1.year, t1.month;
于 2012-12-04T20:15:34.587 回答
0

这可能是一种更好的方法,特别是如果您要在返回数据之前对其进行处理。基本上,您正在将数据来自的表转换为 typeId。

declare @temp table 
([year] int,
[month] int,
typeId int,
data decimal)


insert into @temp
SELECT t1.year, t1.month, 1,  sum(t1.data)
From t1
group by t1.year, t1.month

insert into @temp
SELECT t2.year, t2.month, 2,  sum(t2.data)
From t2
group by t1.year, t1.month


insert into @temp
SELECT t3.year, t3.month, 3,  sum(t3.data)
group by t1.year, t1.month


select t.year, t.month, 
sum(case when t.typeId = 1 then t.data end) as col1, 
sum(case when t.typeId = 2 then t.data end) as col2, 
sum(case when t.typeId = 3 then t.data end) as col3 
from @temp t
group by t.year, t.month
于 2012-12-04T21:24:02.513 回答