如何根据 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;
这样您就可以根据需要引入其他列或合并更复杂的排序逻辑。
我正在尝试编写 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;
这样您就可以根据需要引入其他列或合并更复杂的排序逻辑。