Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 缺少日期的左连接_Sql_Sql Server_Join - Fatal编程技术网

Sql 缺少日期的左连接

Sql 缺少日期的左连接,sql,sql-server,join,Sql,Sql Server,Join,我有一个数据表(FACT.UnitData),其中有列(DayCalendarDate和saleqty),但缺少一些数据: 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.000000

我有一个数据表(
FACT.UnitData
),其中有列(
DayCalendarDate
saleqty
),但缺少一些数据:

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
我有另一个表(
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填写
FACT.UnitData
中缺少的日期(2019-05-12)。
到目前为止,我有以下信息:

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
但这并不能用0.0来填充缺失的日期(2019-05-12)


谢谢您的帮助。

您是否只需要
coalesce()

还请注意,
ORDER BY
使用日历日期,而不是参考值。毕竟,这将是
NULL
,因此它的顺序不正确

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中执行,如下所示:

首先,将处理作为dc的DIM.DayCalendar中的数据

此表上没有进行筛选,因此在此步骤中将检索所有行

接下来,处理将
FACT.UnitData作为ud
的连接。作为LOJ,第一个表中的所有行保持不变(仍然没有过滤),在第二个表中找到的行将加入。这可能会导致第一个表中的行出现不止一次(即,第二个表中每个连接行出现一次)。更重要的是,如果在第二个表中找不到行,则它们的值将设置为NULL

接下来考虑WHERE子句:
ud.UnitID=@unit\u id和ud.LocationID=@location\u id
。“ud”是第二个表,因此所有不符合这些条件的行都将被过滤掉。这意味着当找到空值时,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

请注意,这可能会比第一个查询执行得稍差一些。这两个查询都有点难以阅读和理解,但对于复杂的查询,这种情况会发生。

您确定吗?如果您按
c.Date
订购该怎么办?根据
(NOLOCK)
查询提示,这看起来像
SQL Server
,而不是
MySQL
。您的标签正确吗?另外,您可能希望阅读此-
(NOLOCK)
是一个SQL Server提示,因此我更改了该标记。话虽如此,你不应该使用它,除非你真的知道自己在做什么。@alex_lewis。要用什么填充值?了解左联接返回的内容:内部联接行加上由null扩展的不匹配的左表行。始终知道作为左连接的一部分,您需要什么样的内部连接。一个WHERE或ON,它要求在上的左联接删除任何由NULL扩展的行后右表列不为NULL,即只保留内部联接行,即“将左联接转换为内部联接”。你有,谢谢你的建议。然而,这似乎不起作用。我在服务器上只有读取权限,这是为什么呢?您应该只需要读取权限,而且查询肯定没有问题。请参阅此处的示例(除模式名称外无其他更改)@alex_lewis“这似乎不起作用”您这是什么意思?@MartinBrown。在SQL Server中,当第一个表达式比较复杂时,
ISNULL()
具有更好的性能*(
coalesce()
对其求值两次)。但是,
coalesce()
既标准又更灵活(因为它接受两个以上的参数。@MartinBrown另一个区别是
COALESCE
ISNULL
也有不同的返回类型规则。COALESCE的返回类型将是具有最高优先级的表达式的类型,而
ISNULL
的返回类型将是第一个参数的类型。
ISNULL(CONVERT(位,0),0)
返回一位,但
合并(CONVERT(位,0),0)
将返回一个int。在很多情况下,这可能是一个决定性因素,但在某些情况下,它可能会节省一到两次转换,或者令人头痛的是,在添加coalesce后,为什么您的位列突然变为int。非常感谢——与@GordonLinoff的答案完美结合使用(使用合并方法)。
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