如何在一个月没有匹配项的查询中获取所有月份?

ffu*_*tes 3 sql-server

我需要逐年获取(以填写图表)。然而,我发现第一个月没有任何数据,我想反映这一点。查询是这样的:

SELECT tblMes.id, COUNT(*) AS ingreso
FROM tblTicket
LEFT JOIN tblMes ON MONTH(tblTicket.fechaIngreso) = tblMes.id
WHERE year(fechaIngreso) = 2017
GROUP BY tblMes.id
ORDER BY tblMes.id asc
Run Code Online (Sandbox Code Playgroud)

查询的结果是这样的:

Month | Qty
--------------
"2"   | "1066"
"3"   | "1395"
"4"   | "761"
"5"   | "1316"
"6"   | "879"
"7"   | "1039"
"8"   | "1099"
"9"   | "577"
"10"  | "1064"
"11"  | "1268"
"12"  | "1188"
Run Code Online (Sandbox Code Playgroud)

第一行应该是“1” | “0”

为什么左连接不够?

Aar*_*and 14

我想你只是把你的表倒过来了(第一个表是你想要的所有行,外表是所有可能存在的行)。您还需要将外部表子句作为连接条件 (ON) 的一部分,而不是过滤条件 (WHERE),否则您的外部连接将变成内部连接。

SELECT m.id, COUNT(t.fechaIngreso) AS ingreso
FROM dbo.tblMes AS m
LEFT OUTER JOIN dbo.tblTicket AS t
ON MONTH(t.fechaIngreso) = m.id
AND year(t.fechaIngreso) = 2017
GROUP BY m.id
ORDER BY m.id;
Run Code Online (Sandbox Code Playgroud)

这假设tblMes只是一个有 12 行的表,12 个月中的每一个月都有一行。你也可以很容易地在没有那个表的情况下做到这一点:

;WITH Months(id) AS
(
  SELECT 1 UNION ALL SELECT id+1 FROM Months WHERE id <= 11
)
SELECT m.id, COUNT(t.fechaIngreso) AS ingreso
FROM Months AS m
LEFT OUTER JOIN dbo.tblTicket AS t
ON m.id = MONTH(t.fechaIngreso)
AND YEAR(t.fechaIngreso) = 2017
GROUP BY m.id
ORDER BY m.id;
Run Code Online (Sandbox Code Playgroud)

在足够现代的 SQL Server 版本上,并且索引为fechaIngreso,这可能会表现得更好:

ON t.fechaIngreso >= DATEFROMPARTS(2017, m.id, 1)
  AND t.fechaIngreso < DATEADD(MONTH, 1, DATEFROMPARTS(2017, m.id, 1))
Run Code Online (Sandbox Code Playgroud)

原因是MONTH()andYEAR()函数将强制扫描,因为必须为每一行评估该计算的结果。恕我直言,即使您现在在该列上没有支持索引,也最好避免这项工作。