SQL查询留下加入问题

时间:2016-01-21 10:23:21

标签: mysql sql sql-server join left-join

我有两张表:usersuserlogs

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,它只会提供表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

我尝试了很多不同的方法,但没有成功。

3 个答案:

答案 0 :(得分:2)

尝试将过滤条件移动到左连接中。

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

答案 1 :(得分:1)

如果WHERE子句中的筛选列使用LEFT OUTER JOIN指定,则Join的行为与INNER JOIN完全相同。如果您不希望将LEFT JOIN的行为更改为INNER JOIN,请转到ON&和条件。

    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'

答案 2 :(得分:0)

这个查询应该没问题:

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解释了如何做到这一点。