通过不在另一个表中显示SQL中的特定行
我在高级SQL和stackoverflow方面不是很有经验,所以我会尽力解释我需要什么 假设我有一张名为“Shift”的表和一张名为“Schedule”的表 “班次”包含“班次id、班次开始、班次结束、班次日期、, shift\u函数\u id' shift\U start表示开始时间 shift_end表示结束时间 shift_day表示从0到6开始的一周中的天数 星期天 shift_function_id表示属于shift的函数_id “计划”包含“计划id、计划日期、计划开始、, 计划\结束,计划\功能\ id' schedule_date表示计划的日期 schedule_start表示开始时间 schedule_end表示结束时间 schedule_function_id表示属于 时间表 我想做的是,如果表“Schedule”中不存在来自“Shift”的行,且该行具有给定的特定日期,其中Shift\u start=Schedule\u start和Shift\u end=Schedule\u end和Shift\u function\u id=Schedule\u function\u id,则显示该行 下面是一个例子:通过不在另一个表中显示SQL中的特定行,sql,mariadb,Sql,Mariadb,我在高级SQL和stackoverflow方面不是很有经验,所以我会尽力解释我需要什么 假设我有一张名为“Shift”的表和一张名为“Schedule”的表 “班次”包含“班次id、班次开始、班次结束、班次日期、, shift\u函数\u id' shift\U start表示开始时间 shift_end表示结束时间 shift_day表示从0到6开始的一周中的天数 星期天 shift_function_id表示属于shift的函数_id “计划”包含“计划id、计划日期、计划开始、, 计划\结
SELECT shift_id, shift_day, shift_start, shift_end, function_id, function_name, function_color
FROM Shift
LEFT JOIN Function
ON function_id = shift_function_id
WHERE shift_day = $day
AND NOT EXISTS (
SELECT 1
FROM Schedule
WHERE schedule_date = '$date' AND schedule_start = shift_start AND schedule_end = shift_end AND schedule_function_id = shift_function_id
)
ORDER BY function_name, shift_start, shift_end;
问题是
如果有两个班次具有相同的开始和结束时间,并且表“Schedule”包含一行具有相同的函数id和开始和结束时间,则两个班次都不会显示
以下是表格内容的示例:
时间表
移位
“Shift”中的两行不再显示
我想要什么
如果“Schedule”只有一行包含与“Shift”中给定数据相同的信息,我希望显示另一行
如果“Schedule”有两行具有相同信息,则不显示任何行。它只需要取决于“Schedule”中有多少行具有相同的信息
图像
如果未填写任何内容,则显示起始和结束相同的两行
当我放置一个具有相同开始和结束时间的记录时,它会删除两个移位行
我需要这个,当我只填写一个记录相同的开始和结束时间
我能想到的唯一方法是让NOT EXISTS子句删除所有行,只需使用MIN或MAX Shift_id从重复行中追加1行即可-
SELECT shift_id,
shift_day,
shift_start,
shift_end,
function_id,
function_name,
function_color
FROM shift
LEFT JOIN function
ON function_id = shift_function_id
WHERE shift_day = $day
AND NOT EXISTS (SELECT 1
FROM schedule
WHERE schedule_date = '$date'
AND schedule_start = shift_start
AND schedule_end = shift_end
AND schedule_function_id = shift_function_id)
UNION ALL
SELECT Min(S1.shift_id),
S1.shift_day,
S1.shift_start,
S1.shift_end,
function_id,
function_name,
function_color
FROM shift S1
JOIN shift S2
ON S1.shift_id <> S2.shift_id
AND S1.shift_day = S2.shift_day
AND S1.shift_start = S2.shift_start
AND S1.shift_end = S2.shift_end
LEFT JOIN function
ON function_id = S1.shift_function_id
GROUP BY S1.shift_day,
S1.shift_start,
S1.shift_end,
function_id,
function_name,
function_color
ORDER BY function_name,
shift_start,
shift_end;
是工作示例。如果您的MariaDB版本支持窗口函数,则可以在子查询中使用行号来消除记录的歧义,这些记录在shift_表中具有相同的shift_开始、shift_结束、shift_函数,或者在schedule表中具有相同的schedule_开始、schedule_结束、schedule_函数 然后可以在连接条件中使用记录列组,我将notexits子查询更改为LEFT-join反模式,但这基本上是相同的逻辑
select s.*, f.*
from (
select
s.*,
row_number() over(
partition by shift_start, shift_end, shift_function
order by shift_id
) rn
from shift s
where shift_day = @shift_day
) s
left join (
select
c.*,
row_number() over(
partition by schedule_start, schedule_end, schedule_function
order by schedule_id
) rn
from schedule c
where schedule_date = @schedule_date
) c
on c.schedule_start = s.shift_start
and c.schedule_end = s.shift_end
and c.schedule_function_id = s.shift_function_id
and c.rn = s.rn
left join function f
on f.function_id = s.shift_function_id
where c.rn is null
order by f.function_name, s.shift_start, s.shift_end
你的完美要求还不清楚。请编辑您的问题,并发布更多示例数据和预期结果。@AnkitBajpai我已添加图像。也许这会让事情变得更清楚我很确定这是比我的更好的解决方案。
SELECT shift_id,
shift_day,
shift_start,
shift_end,
function_id,
function_name,
function_color
FROM shift
LEFT JOIN function
ON function_id = shift_function_id
WHERE shift_day = $day
AND NOT EXISTS (SELECT 1
FROM schedule
WHERE schedule_date = '$date'
AND schedule_start = shift_start
AND schedule_end = shift_end
AND schedule_function_id = shift_function_id)
UNION ALL
SELECT Min(S1.shift_id),
S1.shift_day,
S1.shift_start,
S1.shift_end,
function_id,
function_name,
function_color
FROM shift S1
JOIN shift S2
ON S1.shift_id <> S2.shift_id
AND S1.shift_day = S2.shift_day
AND S1.shift_start = S2.shift_start
AND S1.shift_end = S2.shift_end
LEFT JOIN function
ON function_id = S1.shift_function_id
GROUP BY S1.shift_day,
S1.shift_start,
S1.shift_end,
function_id,
function_name,
function_color
ORDER BY function_name,
shift_start,
shift_end;
select s.*, f.*
from (
select
s.*,
row_number() over(
partition by shift_start, shift_end, shift_function
order by shift_id
) rn
from shift s
where shift_day = @shift_day
) s
left join (
select
c.*,
row_number() over(
partition by schedule_start, schedule_end, schedule_function
order by schedule_id
) rn
from schedule c
where schedule_date = @schedule_date
) c
on c.schedule_start = s.shift_start
and c.schedule_end = s.shift_end
and c.schedule_function_id = s.shift_function_id
and c.rn = s.rn
left join function f
on f.function_id = s.shift_function_id
where c.rn is null
order by f.function_name, s.shift_start, s.shift_end