SQL 查询左侧加入问题
SQL query left joining issue
我有两个 table:users
和 userlogs
table1
----------
id | name
----------
1 | A
2 | B
3 | C
4 | D
table2
----------
user_id | date
----------
1 | 2015-12-17
2 | 2015-12-18
3 | 2015-12-19
4 | 2015-12-20
如果我对所选日期进行 LEFT JOIN,它只会提供存在于 table 2.
中的数据
SELECT r.user_id, count(r.user_id) as count
FROM table1 a LEFT OUTER JOIN table2 r ON ( r.user_id = a.id )
WHERE r.created_at BETWEEN '2015-12-17' AND '2015-12-19'
GROUP BY a.id
我得到以下
Result
----------
user_id | count
----------
1 | 1
2 | 1
3 | 1
我需要如下内容:
Result
----------
user_id | count
----------
1 | 1
2 | 1
3 | 1
4 | 0
我尝试了很多不同的方法,但都没有成功。
尝试将过滤条件移动到左连接中。
SELECT
a.id,
count(r.user_id) as count
FROM table1 a
LEFT OUTER JOIN table2 r ON r.user_id = a.id AND
r.created_at BETWEEN '2015-12-17' AND '2015-12-19'
GROUP BY a.id
这个查询应该没问题:
DECLARE @T1 TABLE
(
id INT
, name VARCHAR(50)
);
DECLARE @T2 TABLE
(
[user_id] INT
, [date] DATE
);
INSERT INTO @T1 (id, name)
VALUES (1, 'A'), (2, 'B'), (3, 'C'), (4, 'D');
INSERT INTO @T2 ([user_id], [date])
VALUES (1, '2015-12-17'), (2, '2015-12-18'), (3, '2015-12-19'), (4, '2015-12-20');
SELECT T1.id, COALESCE(T2.Cnt, 0) AS Cnt
FROM (SELECT DISTINCT id FROM @T1) AS T1
LEFT JOIN (
SELECT [user_id], COUNT(*) AS Cnt
FROM @T2
WHERE [date] BETWEEN '2015-12-17' AND '2015-12-19'
GROUP BY [user_id]
) AS T2
ON T2.[user_id] = t1.id;
它输出你所期望的:)
或者像这样将其包装在存储过程中:
CREATE PROCEDURE dbo.YourProcedure
(
@company_id INT
, @start_date DATE
, @end_date DATE
)
as
SELECT T1.id
, T1.department_id
, COALESCE(T2.cnt, 0) AS cnt
FROM (
SELECT DISTINCT id, department_id
FROM users
WHERE company_id = @company_id
) AS T1
LEFT JOIN (
SELECT user_id, COUNT(*) AS cnt
FROM userlogs
WHERE created_at BETWEEN @start_date AND @end_date
GROUP BY user_id
) AS T2
ON T2.user_id = t1.id;
只需将变量传递给它即可调用它。 Using a stored procedure in Laravel 4 解释如何操作。
如果您在 WHERE 子句中使用 LEFT OUTER JOIN 指定的过滤列,则 Join 的行为与 INNER JOIN 完全相同。如果您不希望将 LEFT JOIN 的行为更改为 INNER JOIN,则转到 ON & AND 条件。
SELECT * FROM TABLE1 T1
LEFT OUTER JOIN TABLE2 T2 ON T1.ID = T2.USER_ID
WHERE T2.DATE BETWEEN '2015-12-17' AND '2015-12-19'
同下
SELECT * FROM TABLE1 T1
INNER JOIN TABLE2 T2 ON T1.ID = T2.USER_ID
WHERE T2.DATE BETWEEN '2015-12-17' AND '2015-12-19'
在你的情况下你需要去
SELECT * FROM TABLE1 T1
LEFT OUTER JOIN TABLE2 T2 ON T1.ID = T2.USER_ID
AND T2.DATE BETWEEN '2015-12-17' AND '2015-12-19'
我有两个 table:users
和 userlogs
table1
----------
id | name
----------
1 | A
2 | B
3 | C
4 | D
table2
----------
user_id | date
----------
1 | 2015-12-17
2 | 2015-12-18
3 | 2015-12-19
4 | 2015-12-20
如果我对所选日期进行 LEFT JOIN,它只会提供存在于 table 2.
中的数据SELECT r.user_id, count(r.user_id) as count
FROM table1 a LEFT OUTER JOIN table2 r ON ( r.user_id = a.id )
WHERE r.created_at BETWEEN '2015-12-17' AND '2015-12-19'
GROUP BY a.id
我得到以下
Result
----------
user_id | count
----------
1 | 1
2 | 1
3 | 1
我需要如下内容:
Result
----------
user_id | count
----------
1 | 1
2 | 1
3 | 1
4 | 0
我尝试了很多不同的方法,但都没有成功。
尝试将过滤条件移动到左连接中。
SELECT
a.id,
count(r.user_id) as count
FROM table1 a
LEFT OUTER JOIN table2 r ON r.user_id = a.id AND
r.created_at BETWEEN '2015-12-17' AND '2015-12-19'
GROUP BY a.id
这个查询应该没问题:
DECLARE @T1 TABLE
(
id INT
, name VARCHAR(50)
);
DECLARE @T2 TABLE
(
[user_id] INT
, [date] DATE
);
INSERT INTO @T1 (id, name)
VALUES (1, 'A'), (2, 'B'), (3, 'C'), (4, 'D');
INSERT INTO @T2 ([user_id], [date])
VALUES (1, '2015-12-17'), (2, '2015-12-18'), (3, '2015-12-19'), (4, '2015-12-20');
SELECT T1.id, COALESCE(T2.Cnt, 0) AS Cnt
FROM (SELECT DISTINCT id FROM @T1) AS T1
LEFT JOIN (
SELECT [user_id], COUNT(*) AS Cnt
FROM @T2
WHERE [date] BETWEEN '2015-12-17' AND '2015-12-19'
GROUP BY [user_id]
) AS T2
ON T2.[user_id] = t1.id;
它输出你所期望的:)
或者像这样将其包装在存储过程中:
CREATE PROCEDURE dbo.YourProcedure
(
@company_id INT
, @start_date DATE
, @end_date DATE
)
as
SELECT T1.id
, T1.department_id
, COALESCE(T2.cnt, 0) AS cnt
FROM (
SELECT DISTINCT id, department_id
FROM users
WHERE company_id = @company_id
) AS T1
LEFT JOIN (
SELECT user_id, COUNT(*) AS cnt
FROM userlogs
WHERE created_at BETWEEN @start_date AND @end_date
GROUP BY user_id
) AS T2
ON T2.user_id = t1.id;
只需将变量传递给它即可调用它。 Using a stored procedure in Laravel 4 解释如何操作。
如果您在 WHERE 子句中使用 LEFT OUTER JOIN 指定的过滤列,则 Join 的行为与 INNER JOIN 完全相同。如果您不希望将 LEFT JOIN 的行为更改为 INNER JOIN,则转到 ON & AND 条件。
SELECT * FROM TABLE1 T1
LEFT OUTER JOIN TABLE2 T2 ON T1.ID = T2.USER_ID
WHERE T2.DATE BETWEEN '2015-12-17' AND '2015-12-19'
同下
SELECT * FROM TABLE1 T1
INNER JOIN TABLE2 T2 ON T1.ID = T2.USER_ID
WHERE T2.DATE BETWEEN '2015-12-17' AND '2015-12-19'
在你的情况下你需要去
SELECT * FROM TABLE1 T1
LEFT OUTER JOIN TABLE2 T2 ON T1.ID = T2.USER_ID
AND T2.DATE BETWEEN '2015-12-17' AND '2015-12-19'