Mysql SQL:返回互补值的查询
这是我问题的简化版本。我有一个包含姓名的表和一个包含有限时间段列表(比如说一周中的几天)的表。链接器表链接这两个表。使用这三个表的简单内部联接,我可以显示每个表的可用性:Mysql SQL:返回互补值的查询,mysql,sql-server,Mysql,Sql Server,这是我问题的简化版本。我有一个包含姓名的表和一个包含有限时间段列表(比如说一周中的几天)的表。链接器表链接这两个表。使用这三个表的简单内部联接,我可以显示每个表的可用性: | id | day | |******|*****| | 1 | MO | | 1 | TU | | 1 | WE | | 1 | TH | | 1 | FR | | 1 | SU | | 2 | MO | | 2 | TU | | 2 | W
| id | day |
|******|*****|
| 1 | MO |
| 1 | TU |
| 1 | WE |
| 1 | TH |
| 1 | FR |
| 1 | SU |
| 2 | MO |
| 2 | TU |
| 2 | WE |
| 2 | FR |
| 2 | SA |
| 2 | SU |
由于大多数用户大部分时间都是可用的,我想运行一个查询来显示他们何时不可用:
| id | day |
|******|*****|
| 1 | SA |
| 2 | TH |
我知道如何使用外部连接找到集合的补码,在哪里。。。为空,但我看不出如何将这些互补值与个体联系起来。这可能是很明显的,但我已经坚持了几个小时了。请注意,我无法控制DB设计
编辑:很抱歉我的问题不够清楚
我再试试看
该表包含以下列:id(PK)、first_name、last_name、DOB等。
表中的时间段有以下列:id(PK)、时间段
链接器表individualstimeslots具有以下列:id(PK)、IDIDividual(FK)、idtimeslot(FK)
以下查询返回个人可用时的时隙概览
SELECT
i.first_name, i.last_name, t.timeslot
FROM
individuals as i
inner join individualstimeslots as it on it.idindividual = i.id
inner join timeslots as t on t.id = it.idtimeslot
(结果类似于上面的第一个表,除了使用名字和姓氏而不是id)
如果我想知道id为1的个人何时不可用,我可以使用以下查询:
SELECT
i.first_name, i.last_name, t.timeslot, t2.timeslot as all
FROM
individuals as i
inner join individualstimeslots as it on it.idindividual = i.id and i.id = 1
inner join timeslots as t on t.id = it.idtimeslot
right outer join timeslots as t2 on t.id = t2.id
结果如下:
| JOHN | DOE | MO | MO |
| JOHN | DOE | TU | TU |
| JOHN | DOE | WE | WE |
| JOHN | DOE | TH | TH |
| JOHN | DOE | FR | FR |
| | | | SA |
| JOHN | DOE | MO | SU |
如果我只想显示John Doe不可用的时间段,我可以在查询中添加以下条件:
WHERE t.timeslot IS NULL
结果:
| | | | SA |
然而,该结果并不明确指id=1的个体。
我所追求的是一个查询,该查询仅用于此目的,并在所有(选定)个人不可用时显示:
| JOHN | DOE | SA |
| JANE | DOE | TH |
希望我现在已经说得更清楚了。不幸的是,我不认为你可以通过一个简单的查询来解决这个问题(尽管我希望被证明是错的)。 但是您可以轻松地创建一个游标,在所有(相关)个体之间循环,并为每个个体执行外部连接查询。然后,您可以将结果插入到临时表中,并在最后从中进行选择。
您已经标记了mysql和sql server,所以我不知道您使用哪种语言。但这两种情况都有可能:)此查询似乎可以满足您的要求。你甚至可以在没有CTE的情况下重写这篇文章,但我认为它更清晰
INSERT INTO dbo.days (namedays) VALUES
('Monday'),
('Tuesday'),
('Wednesday'),
('Thursday'),
('Friday'),
('Saturday'),
('Sunday')
INSERT INTO availability (ID,namedays) VALUES
(1,'Monday'),
(1,'Tuesday'),
(1,'Thursday'),
(2,'Monday'),
(2,'Saturday')
;WITH CTE AS (
SELECT DISTINCT a.ID AS ID ,d.namedays FROM availability a
CROSS JOIN dbo.days d)
SELECT CTE.ID, CTE.namedays FROM CTE
LEFT OUTER JOIN availability a
ON a.ID = CTE.ID AND a.namedays = CTE.namedays
WHERE a.ID IS NULL
你能解释一下我如何将这些互补值链接到个人吗?我相信,与你已有的查询相比,个人表和时隙表之间的
交叉连接将得到你想要的结果,但这几乎是100%不可能的,因为我不知道你的数据是什么样子。您能否共享表中的示例数据以及当前用于获取上述第一个结果的SQL查询。为每个表发布一个数据示例,我们将提供一个很好的查询:)如果没有它,这是不可能的。为什么不创建一个包含所有可用天数的表呢?然后从该表中创建一个查询,并在当前表为null的位置左键联接当前表。