SQL:如何删除由 CASE WHEN 语句创建的重复行
Posted
技术标签:
【中文标题】SQL:如何删除由 CASE WHEN 语句创建的重复行【英文标题】:SQL: How to remove duplicate rows created by CASE WHEN statement 【发布时间】:2021-10-11 06:25:30 【问题描述】:我有两张桌子:(A) 健身房的顾客和 (B) 餐厅的顾客。我想在表 (A) 中创建一个指标来指示同一天去过健身房和餐厅的顾客。为此,我使用了以下 SQL 脚本,但它创建了重复的行:
SELECT *,
CASE WHEN a.GymDate = b.RestaurantDate THEN 'Meal + Gym on the same day'
ELSE 'Gym Only' END AS 'Meal+Gym'
FROM Table_A a
LEFT JOIN Table_B b
ON a.customerid = b.customerid;
我可以知道如何只保留 Table_A,但添加了“膳食+健身房”指示器吗?谢谢!
【问题讨论】:
请显示样本数据和所需结果。您有单独的客户表吗?此外,您的描述和查询返回不同的结果。如果某天一个客户同时去,而某天一个客户只去一个怎么办? 它创建了重复的行 - 它更可能是创建重复行的连接,而不是 CASE WHEN。如果 a 中有 2 行 ID 为 1,B 中有 2 行 ID 为 1,则您将获得 4 行。如果通过“创建重复”你的意思是 CASE WHEN 将一些值隐藏到它的 ELSE 中导致行看起来像重复,那是你真正需要用 WHERE 控制的东西 ACASE
不会创建行,它只是一个标量表达式。就像如果你有一个像YourColumn + OtherColumn
这样的表达式不会创建新行。如果您的 FROM
和 WHERE
要求数据集中有哪些行。
【参考方案1】:
case 表达式不会生成行,它是您的联接生成了重复的行。您可以将日期谓词添加到连接条件,并仅检查是否存在记录,例如
SELECT *,
CASE WHEN b.customerid IS NOT NULL THEN 'Meal + Gym on the same day'
ELSE 'Gym Only'
END AS [Meal+Gym]
FROM Table_A a
LEFT JOIN Table_B b
ON a.customerid = b.customerid
AND a.GymDate = b.RestaurantDate;
如果每个客户/日期的 table_B 不是唯一的,那么您可能需要执行以下操作来防止重复:
SELECT *,
CASE WHEN r.RestaurantVisit IS NOT NULL THEN 'Meal + Gym on the same day'
ELSE 'Gym Only'
END AS [Meal+Gym]
FROM Table_A a
OUTER APPLY
( SELECT TOP 1 1
FROM Table_B b
WHERE a.customerid = b.customerid
AND a.GymDate = b.RestaurantDate
) AS r (RestaurantVisit);
注意虽然使用单引号适用于列别名,但这根本不是一个好习惯,因为它使您的列别名与字符串文字(而不是上下文)无法区分。即使这对您来说很清楚,但对其他人来说可能不是,并且由于阅读:编写代码的比例约为 10:1,因此编写易于阅读的代码很重要。因此,我使用方括号代替您的列名
【讨论】:
【参考方案2】:我会从一张顾客表开始,这样您就可以得到既没有去过健身房也没有去过餐厅的顾客的指标。
然后:
select c.*,
(case when exists (select 1
from table_a a join
table_b b
on a.customerid = b.customerid and
a.GymDate = b.RestaurantDate
where a.customerid = c.customerid
)
then 1 else 0
end) as same_day_gym_restaurant_flag
from customers c;
【讨论】:
【参考方案3】:您可以使用CASE WHEN EXISTS
代替LEFT JOIN
:
SELECT *,
CASE WHEN EXISTS (
SELECT 1 FROM Table_B b
WHERE a.customerid = b.customerid
AND a.GymDate = b.RestaurantDate)
THEN 'Meal + Gym on the same day'
ELSE 'Gym Only'
END AS 'Meal+Gym'
FROM Table_A a
这假设您在结果中不需要 Table_B 中的任何数据。
【讨论】:
以上是关于SQL:如何删除由 CASE WHEN 语句创建的重复行的主要内容,如果未能解决你的问题,请参考以下文章
SQL Select CASE-WHEN - 如何从电话号码中删除格式