就像这里要问的许多问题一样,我需要能够使用2个不同的WHERE子句两次选择同一列。不幸的是,存在一个问题,因为我还试图解决另一个常见问题,因为使用WHERE子句,即使使用LEFT JOIN时,使用COUNT()时也无法显示所有单元格。
所以有两个问题。首先,尽管有LEFT JOIN,WHERE子句仍删除存在NULL的选项之一。
第二,由于WHERE子句,我无法将2个查询合并为一个。
我尝试在内部和外部,子查询,OUTER APPLY和UNION中使用COUNT()的'CASE WHEN'。他们都不显示我的需求。
所以我的第一张桌子显示了学生及其学校的房子:
Table - Houses
StudentID | House
---------------------
1 | A
2 | B
3 | C
4 | D
5 | A
6 | B
7 | C
8 | D
第二张表显示了房屋得分:
Table - Points
StudentID | House | PointAwardedDate
------------------|-------------------
1 | A | 01/04/2019 10:04:00
1 | A | 17/05/2019 11:25:00
1 | A | 17/06/2019 12:58:00
2 | B | 02/02/2019 08:54:00
3 | C | 03/03/2019 15:46:00
4 | D | 17/06/2019 13:14:00
5 | A | 05/06/2019 15:34:00
6 | B | 01/02/2019 12:32:00
7 | C | 17/06/2019 11:57:00
8 | D | 15/04/2019 09:24:00
8 | D | 17/06/2019 09:45:00
使用以下代码,我可以挑选自上个星期日(2019年6月16日)以来授予的奖项,并显示每所房屋获得了多少奖励:
SELECT
Houses.House,
COUNT(Points.StudentID) AS PointsCount
FROM Houses
LEFT JOIN Points
ON Houses.STudentID = Points.StudentID
WHERE Points.PointsAwardedDate >= (SELECT DATEADD(wk, DATEDIFF(wk, 6, GETDATE()), 6))
GROUP BY Houses.House
哪个节目
House | PointsCount
-------|--------------
A | 1
C | 1
D | 2
问题1:我需要这样显示该表:
House | PointsCount
-------|--------------
A | 1
B | 0
C | 1
D | 2
问题2-我们需要显示另一列,列出整个学年的分数。因此,我们拥有的(有效的)代码是:
SELECT DISTINCT
Houses.House,
COUNT(Points.StudentID) AS PointsCountYear
FROM Houses
LEFT JOIN Points
ON Houses.STudentID = Points.StudentID
WHERE Points.PointsAwardedDate >= (
SELECT
TOP 1 Points.PointsAwardedDate
FROM TblSchoolManagementTermDates
WHERE Points.PointsAwardedDate <=
CONVERT(datetime, GETDATE())
AND intTerm = 1
ORDER BY intSchoolYear DESC)
AND txtDate <= (
SELECT TOP 1 txtFinishDate
FROM TblSchoolManagementTermDates
WHERE txtFinishDate >=
CONVERT(datetime, GETDATE())
ORDER BY intSchoolYear ASC)
GROUP BY Pups.txtAcademicHouse
此处的学期日期为2018年9月1日至2019年8月31日
这将拔出下表:
House | PointsCountYear
-------|-----------------
A | 4
B | 2
C | 2
D | 3
我们需要能够将2组合在一起,因此我们的决赛桌看起来像这样:
House | PointsCount | PointsCountYear
-------|--------------|-----------------
A | 1 | 4
B | 0 | 2
C | 1 | 2
D | 2 | 3
我们了解到,第一部分的问题在于WHERE子句正在过滤出房屋B的任何数据,因此即使使用LEFT JOIN也不会显示该数据,但是我们不确定如何将其显示在另一位置仍然保留正确数据的方式。
非常感谢您的帮助。
谢谢 罗布
答案 0 :(得分:1)
我尝试为SQLServer回答: 问题1的可能解决方案:
CREATE TABLE #HOUSES
(
STUDENT_ID INT NOT NULL
, HOUSE VARCHAR(1) NOT NULL
);
INSERT INTO #HOUSES VALUES (1, 'A')
, (2, 'B')
, (3, 'C')
, (4, 'D')
, (5, 'A')
, (6, 'B')
, (7, 'C')
, (8, 'D');
CREATE TABLE #POINTS
(
STUDENT_ID INT NOT NULL
, HOUSE VARCHAR(1) NOT NULL
, POINTAWARDEDDATE DATE NOT NULL
);
INSERT INTO #POINTS VALUES
(1, 'A', '01/04/2019 10:04:00'),
(1, 'A', '17/05/2019 11:25:00'),
(1, 'A', '17/06/2019 12:58:00'),
(2, 'B', '02/02/2019 08:54:00'),
(3, 'C', '03/03/2019 15:46:00'),
(4, 'D', '17/06/2019 13:14:00'),
(5, 'A', '05/06/2019 15:34:00'),
(6, 'B', '01/02/2019 12:32:00'),
(7, 'C', '17/06/2019 11:57:00'),
(8, 'D', '15/04/2019 09:24:00'),
(8, 'D', '17/06/2019 09:45:00')
;
SELECT H.HOUSE
, COUNT(P.POINTAWARDEDDATE) AS POINTSCOUNT
FROM
(
SELECT HOUSE
FROM #HOUSES
GROUP BY HOUSE) H
LEFT JOIN #POINTS P
ON H.HOUSE = P.HOUSE
AND P.POINTAWARDEDDATE >= (SELECT DATEADD(wk, DATEDIFF(wk, 6, GETDATE()), 6))
GROUP BY H.HOUSE
结果:
HOUSE, POINTSCOUNT
A 1
B 0
C 1
D 2
答案 1 :(得分:1)
您可以通过条件聚合来做到这一点:
SELECT
h.House,
SUM(CASE
WHEN p.PointsAwardedDate >= DATEADD(wk, DATEDIFF(wk, 6, GETDATE()), 6) THEN 1
ELSE 0
END) AS PointsCount,
SUM(CASE
WHEN p.PointsAwardedDate >= '2018-09-01' AND p.PointsAwardedDate < '2019-09-01' THEN 1
ELSE 0
END) AS PointsCountYear
FROM Houses AS h
LEFT JOIN Points AS p
ON h.STudentID = p.StudentID
GROUP BY h.House
请参见demo。
结果:
> House | PointsCount | PointsCountYear
> :---- | ----------: | --------------:
> A | 1 | 4
> B | 0 | 2
> C | 1 | 2
> D | 2 | 3
答案 2 :(得分:0)
尝试
SELECT h.house
, COUNT(P.PointsAwardedDate) AS POINTSCOUNT
FROM
(
SELECT StudentId,house
FROM HOUSES
) H
LEFT JOIN POINTS P
ON H.[StudentId] = P.StudentId
AND P.[PointsAwardedDate] >= (SELECT DATEADD(wk, DATEDIFF(wk, 6, GETDATE()), 6))
GROUP BY h.house