如何通过匹配中存在的记录和不存在的记录获取组的结果?

问题描述 投票:-2回答:2

问题:我需要做一个SELECT查询。

我需要做一个SELECT查询,返回的是 shift_id 哪儿day_of_weekIN (0,1,2,3,4)NOT IN (5,6),如:

"找到周日至周四的轮班日(周五至周六没有记录)"

DB结构。

shifts:

shift_id - int,主键...--------------------------------------------------------------------其他栏目

shift_days:

shift_day_id - int, primary keyshift_id - int, shift的外键 tableday_of_week - int, 其中0 = Sunday, 1 = Monday,..., 6 - Saturday...。         - 更多列

例:如果轮班时间是周一至周五,那么

  • 如果班期是周一至周五,那么 shift_days 只有5条记录与 day_of_week 1至5岁
  • 如果班期是周日至周四,那么 shift_days 只有5条记录与 day_of_week 从0到4

DB Fiddles

P.S.我能够想到这个查询。

SELECT shift_id
FROM (
    SELECT shift_id, STRING_AGG(day_of_week, ',') AS 'days_of_week'
    FROM shift_days
    GROUP BY shift_id
) AS sdw
WHERE sdw.days_of_week = '0,1,2,3,4'

但我不知道如何保证顺序是升序的'0,1,2,3,4',我想看看是否有其他的方法可以替代使用STRING_AGG,以防我想在不同的SQL方言中使用。

P.P.S.:我想知道是否有使用STRING_AGG的替代方案,以防我想用于不同的SQL方言。

再次强调的是任何与day_of_week (5,6)匹配的shift都是错误的匹配,因为我想排除这些记录,而且我想包括(0,1,2,3,4)记录,这些记录必须都是0-4。

sql sql-server grouping sql-server-2017
2个回答
1
投票

可以试试下面的查询。

如果你想让所有的班次没有 day_of_week 5,6

SELECT DISTINCT shift_id
FROM shift_days S
WHERE NOT EXISTS (SELECT 1 FROM shift_days T WHERE T.shift_id=S.shift_id AND 
T.day_of_week in (5, 6))

如果你想让所有的班次都有 day_of_week 0,1,2,3,4

SELECT  shift_id FROM shift_days S
WHERE NOT EXISTS (SELECT 1 FROM shift_days T WHERE T.shift_id=S.shift_id AND 
T.day_of_week in (5, 6))
and day_of_week in (0,1,2,3,4)
group by shift_id having count(1)=5

供参考 点击这里查看演示


1
投票
group by shift_id
having
    count(case when day_of_week in (5, 6) then 1 end) = 0
    and count(distinct day_of_week) = 5
© www.soinside.com 2019 - 2024. All rights reserved.