如何根据 SQL 服务器 CASE 语句检索列的单个记录

How to retrieve single record for a column based on SQL Server CASE statement

我正在尝试编写 SQL 服务器 CASE 语句,以根据以下条件检索学生的类别。

如果 student_category table 中的 category 列同时具有 'X' 和 'Y' 值,而 student_id 值来自 student table,则只显示值为'Y'的记录。

如果 category 具有值 'X' 或 'Y',则显示具有该值的记录。

如果 category 没有值 'X' 或 'Y',则为该列显示空白,即如果除 'X' 或 [= 之外还有任何其他类别31=],显示空白。

因此,每个 student_id 我应该只有一行数据,即使它们有多个类别。但是,我仍然为每个 student_id 获得多个类别的多条记录。关于我可能遗漏的任何想法?

SELECT DISTINCT
    s.student_id,
    CASE
       WHEN sc.category = 'X' AND sc.category = 'Y' THEN 'Y'
       WHEN sc.category = 'X' OR sc.category = 'Y' THEN sc.category
       ELSE ''
    END AS student_cat
FROM
    student s
LEFT JOIN
    student_category sc ON s.student_id = sc.student_id

我想你想要聚合。

select s.student_id, min(sc.category) as student_cat
from student s left join
     student_category sc
     on s.student_id = sc.student_id
group by s.student_id;

我无法从你的问题中判断出来;你可能想要 max() 而不是 min().

你有两行 returned,因为无论你在你的 CASE 语句中加入什么条件,对于某个学生 ID,student 和 [=21 之间的连接有两条记录=].如果没有某种聚合,您将有两行。

有几种方法可以解决这个问题。我会这样做:

SELECT  s.student_id,
        --Check how many of each category there are for the student
        CASE WHEN sc.Number_of_x = 1 AND sc.Number_of_y = 1 THEN 'Y'
             WHEN sc.Number_of_x = 1 AND sc.Number_of_y = 0 THEN 'X'
             WHEN sc.Number_of_x = 0 AND sc.Number_of_y = 1 THEN 'Y'
                                                            ELSE ''
        END AS student_cat
FROM    student AS s
        LEFT JOIN (
                  --Aggregate the categories per student so that we only have 1 line
                  --per student_id
                  SELECT    student_id,
                            SUM( IIF( sc.category = 'X', 1, 0 ) ) AS Number_of_x,
                            SUM( IIF( sc.category = 'Y', 1, 0 ) ) AS Number_of_y,
                  FROM      student_category AS sc
                  GROUP BY  student_id
                  ) AS sc
            ON      s.student_id = sc.student_id

通过这种方式,您首先将子查询中的 student_category table 聚合到每个学生 return 1 行,然后检查这些计数以确定类别。

这是假设只有 X 和 Y 两个类别,并且任何一个类别都只能有 0 或 1 个。

我发现在使用 DISTINCT 或 CASE 语句编写查询以查看它看起来像原始数据以及有多少行之前,只需编写 SELECT * 数据样本会很有帮助。

with data as (
    select *,
        row_number() over (
            partition by s.student_id order by sc.category desc) as rn
    from student s left outer join student_category sc
        on s.student_id = sc.student_id
)
select * from data where rn = 1;

这样您就可以根据需要引入其他列或合并更复杂的排序逻辑。