我有一个数据表(SELECT *
FROM OPENROWSET('SQLNCLI', 'Server=server.database.windows.net;Database=DBName;UID=Admin;PWD=********, 'select * from tablename;')
),其中有列(FACT.UnitData
和DayCalendarDate
),但缺少一些数据:
SalesQty
我有另一个表(DayCalendarDate SalesQty
2019-05-13 00:00:00.0000000 36
2019-05-11 00:00:00.0000000 105
2019-05-10 00:00:00.0000000 50
2019-05-09 00:00:00.0000000 30
2019-05-08 00:00:00.0000000 22
),其中有1列(DIM.DayCalendar
)是连续的,因此没有丢失的日期:
Date
我想加入这两个表并在Date
2019-05-13 00:00:00.0000000
2019-05-12 00:00:00.0000000
2019-05-11 00:00:00.0000000
2019-05-10 00:00:00.0000000
2019-05-09 00:00:00.0000000
2019-05-08 00:00:00.0000000
中用0.0填写缺失的日期(2019-05-12)。到目前为止,我有以下内容:
FACT.UnitData
但这不会用0.0填写缺失的日期(2019-05-12)。
感谢您的帮助。
答案 0 :(得分:4)
您只需要coalesce()
吗?
SELECT c.Date, COALESCE(ud.SalesQty, 0) as SalesQty
FROM DIM.DayCalendar c LEFT JOIN
FACT.UnitData AS ud
ON c.Date = ud.DayCalendarDate
ORDER BY c.Date DESC;
还要注意,ORDER BY
使用日历日期,而不是参考值。毕竟,这将是NULL
,所以它的顺序不正确。
答案 1 :(得分:1)
DECLARE @unit_id INT = 71907
DECLARE @location_id INT = 59
SELECT dc.Date, ud.SalesQty
FROM DIM.DayCalendar AS dc
LEFT JOIN FACT.UnitData AS ud
ON dc.Date = ud.DayCalendarDate
WHERE ud.UnitID = @unit_id AND ud.LocationID = @location_id
ORDER BY dc.Date DESC
截至目前为止我所看到的查询(我看不到NOLOCK,也许已经进行了其他编辑)将在SQL中执行,如下所示:
首先,将处理来自DIM.DayCalendar AS dc
的数据。
此表上没有进行任何过滤,因此在此步骤中将检索所有行。
接下来,处理到FACT.UnitData AS ud
的联接。作为LOJ,第一个表中的所有行都将保留(仍不进行过滤),并且第二个表中的行将被合并。这可能导致第一个表中的行出现多次(即,表中每个连接的行均出现一次)第二张表)。更重要的是,如果在第二张表中未找到任何行,则它们的值将设置为NULL。
接下来,将考虑WHERE子句:ud.UnitID = @unit_id AND ud.LocationID = @location_id
。 “ ud”是第二个表,因此将过滤掉所有不符合这些条件的行。这意味着当找到NULL时,where子句将解析为False,因此将从第二张表中未检索到数据的所有行都将被过滤掉。
这就是您丢失日期的方式–外部联接成功,但是随后删除了所有“找不到数据”行。下一个效果与将其设为内部联接一样。
最直接的解决方法是将filterig条件移到join子句中,如下所示:
SELECT dc.Date, ud.SalesQty
FROM DIM.DayCalendar AS dc
LEFT JOIN FACT.UnitData AS ud
ON dc.Date = ud.DayCalendarDate
AND ud.UnitID = @unit_id
AND ud.LocationID = @location_id
ORDER BY dc.Date DESC
这将在第二个表中找到较少的联接行,但是由于它是外部联接,因此第一个表中的所有行都将包含在结果集中。
另一种版本是在where子句中检查NULL:
SELECT dc.Date, ud.SalesQty
FROM DIM.DayCalendar AS dc
LEFT JOIN FACT.UnitData AS ud
ON dc.Date = ud.DayCalendarDate
WHERE ud.UnitID = isnull(@unit_id, ud.UnitID)
AND ud.LocationID = isnull(@location_id, ud.LocationID)
ORDER BY dc.Date DESC
请注意,这可能会比第一个查询执行得差一些。这两种查询都很难阅读和理解,但是对于复杂的查询,这将会发生。