Tim*_*ter 4 t-sql sql-server join sql-server-2005
这是漫长的一天,也许这是一个简单的问题,但无论如何我都被卡住了.
基本上我有两个相似的表Sales和Forecasts.我正在尝试创建一个视图,从两个表中选择行,并选择给定模型+月份+国家/地区的任何内容.如果两个表都包含数据,则Sales具有优先级,这意味着Forecast应省略行.
为了简化查询我正在使用CTE.实际上两个表的模式是不同的,并且连接了许多表,还Forecasts包含仅显示最后一个的历史行.
我创建了一个简化的架构和数据来向您展示我正在尝试做的事情:
WITH Sales AS
(
SELECT
ID, Model, Month, Country,
Amount = Count,
[Forecast / Sales] = 'Sales'
FROM dbo.Sales
)
, Forecasts AS
(
SELECT
ID, Model, Month, Country,
Amount = Count,
[Forecast / Sales] = 'Forecast'
FROM dbo.Forecast
)
SELECT ID = COALESCE(s.ID, fc.ID),
Model = COALESCE(s.Model, fc.Model),
Month = COALESCE(s.Month, fc.Month),
Country = COALESCE(s.Country, fc.Country),
Amount = COALESCE(s.Amount, fc.Amount),
[Forecast / Sales] = COALESCE(s.[Forecast / Sales], fc.[Forecast / Sales])
FROM Sales s
FULL OUTER JOIN Forecasts fc
ON s.Model = fc.Model
AND s.Month = fc.Month
AND s.Country = fc.Country
ORDER BY ID,Month,Country,Model
Run Code Online (Sandbox Code Playgroud)
这是一个带有示例数据的sql-fiddle:http://sqlfiddle.com/#!3/9081b/9/2
结果:
ID MODEL MONTH COUNTRY AMOUNT FORECAST / SALES
1 ABC December, 01 2013 00:00:00+0000 Germany 777 Sales
2 ABC January, 01 2014 00:00:00+0000 Germany 999 Sales
3 ABC February, 01 2014 00:00:00+0000 Germany 900 Sales
3 ABC February, 01 2014 00:00:00+0000 Germany 900 Sales
4 ABC January, 01 2014 00:00:00+0000 UK 600 Forecast
4 ABC February, 01 2014 00:00:00+0000 UK 444 Sales
5 ABC March, 01 2014 00:00:00+0000 UK 500 Forecast
Run Code Online (Sandbox Code Playgroud)
此查询根据ID和源(最后一列)返回重复项.
3 ABC February, 01 2014 00:00:00+0000 Germany 900 Sales
3 ABC February, 01 2014 00:00:00+0000 Germany 900 Sales
Run Code Online (Sandbox Code Playgroud)
显然,对于该模型+月份+国家/地区组合,Sales行会被多个Forecast箭头复制.Sales如果没有重复项可用Sales+ Forecast行,Forecast如果没有Sales行,我如何只获得行?
您的查询的问题不是使用COALESCE,而只是使用JOIN.Forecast表中有2行具有相同的组合Model, Month, Country,行为ID2和3:
??????????????????????????????????????????????????????????
? ID ? Model ? Month ? Country ? Count ?
??????????????????????????????????????????????????????????
? 2 ? ABC ? 2014-02-01 00:00:00.000 ? Germany ? 1100 ?
? 3 ? ABC ? 2014-02-01 00:00:00.000 ? Germany ? 900 ?
??????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
它们都与表中的第ID3 行连接Sales:
??????????????????????????????????????????????????????????
? ID ? Model ? Month ? Country ? Count ?
??????????????????????????????????????????????????????????
? 3 ? ABC ? 2014-02-01 00:00:00.000 ? Germany ? 900 ?
??????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
并且由于您的查询正在使用COALESCE(s.ID, fc.ID),因此您ID在结果中获得2行,其中包含3 行
Lamak的答案提供了结果中重复行的原因.这是一个解决方案:
WITH Sales AS
( ... )
, Forecasts AS
( ...)
, Combos AS -- get all distinct
( -- model + month + country
SELECT Model, Month, Country -- combinations
FROM Sales -- from Sales
UNION -- this is UNION DISTINCT
SELECT Model, Month, Country
FROM Forecasts -- and Forecasts
)
SELECT ID = COALESCE(s.ID, f.ID),
c.Model,
c.Month,
c.Country,
Amount = COALESCE(s.Amount, f.Amount),
[Forecast / Sales] = COALESCE(s.[Forecast / Sales],
f.[Forecast / Sales])
FROM Combos c
LEFT JOIN Sales s
ON s.Model = c.Model
AND s.Month = c.Month
AND s.Country = c.Country
LEFT JOIN Forecasts f
ON s.Model IS NULL -- join Forecasts only if there is no Sales
AND f.Model = c.Model
AND f.Month = c.Month
AND f.Country = c.Country
ORDER BY ID, Month, Country, Model ;
Run Code Online (Sandbox Code Playgroud)
测试时间:SQL-Fiddle
| 归档时间: |
|
| 查看次数: |
2274 次 |
| 最近记录: |