Sql server 即使sql server中没有记录,也返回数据

Sql server 即使sql server中没有记录,也返回数据,sql-server,tsql,Sql Server,Tsql,我有一张名为students的表格,即使某一特定课程、特定年份的数据不存在,我也会得到记录 以下是我的数据: CREATE TABLE students ([Year] int, Course varchar(50), [Number of students] int); INSERT INTO students VALUES (2018, 'Maths ', 10), (2019, 'M

我有一张名为students的表格,即使某一特定课程、特定年份的数据不存在,我也会得到记录

以下是我的数据:

CREATE TABLE students ([Year] int,
                       Course varchar(50),
                       [Number of students] int);

INSERT INTO students
VALUES (2018, 'Maths ', 10),
       (2019, 'Maths', 15),
       (2018, 'Economics', 8),
       (2018, 'Social Studies', 3),
       (2019, 'Social Studies', 4),
       (2018, 'Science', 7);
如何获得如下输出:

Year    Course  Students
2018    Maths   10
2019    Maths   15
2018    Economics   8
2019    Economics   0
2018    Social Studies  3
2019    Social Studies  4
2018    Science 7
2019    Science 0
如果在(‘经济学’、‘数学’)中使用where子句,例如where课程,请不要手动编写代码值。希望在SQL server中改用变量


谢谢。

您可以加入日历表:

WITH years AS (
    SELECT 2018 AS Year UNION ALL
    SELECT 2019
),
courses AS (
    SELECT 'Maths' AS Course UNION ALL
    SELECT 'Economics' UNION ALL
    SELECT 'Social Studies' UNION ALL
    SELECT 'Science'
)

SELECT
    y.Year,
    c.Course,
    COALESCE(s.Students, 0) AS Students
FROM year y
CROSS JOIN courses c
LEFT JOIN Students s
    ON s.Year = y.Year AND s.Course = c.Course;

这会得到您想要的结果,但是,如果有一个较大的表,
DISTINCT
可能会变得昂贵:

SELECT Y.[Year],
       C.Course,
       ISNULL(S.[Number of students],0) AS [Number of students]
FROM (SELECT DISTINCT [Year] FROM dbo.students) Y
     CROSS JOIN (SELECT DISTINCT Course FROM dbo.students) C
     LEFT JOIN dbo.students S ON Y.[Year] = S.[Year]
                             AND C.Course = S.Course;
理想情况下,您应该有一个单独的表,其中包含您的学年和课程数据,然后查询可以“缩短”为:


感谢您尝试将示例数据发布为DDL和DML,但请先检查SQL是否有效。:)谢谢@TimBiegeleisen。你的和我的差不多,除了使用文字值作为值。这太完美了!非常感谢大家,我每年都要这么做,前进和后退,所以我不想硬编码2016年、2017年、2018年等年份,但也要感谢大家well@SindhuB理想情况下,您应该维护年度和课程的表格。给出的两个答案实际上都只是权宜之计。
SELECT Y.[Year],
       C.Course,
       ISNULL(S.[Number of students],0) AS [Number of students]
FROM dbo.Years Y
     CROSS JOIN dbo.Courses C
     LEFT JOIN dbo.students S ON Y.[Year] = S.[Year]
                             AND C.Course = S.Course;