我需要获取所有DISTINCT用户(根据不可用时间段不可用的用户除外)。
SHIFT
表:
user
+------+-----------+--------------------------------------+
| id | firstname | content |
+------+-----------+--------------------------------------+
| 13 | John | ... |
| 44 | Marc | ... |
| 55 | Elise | ... |
+------+-----------+--------------------------------------+
期表:
unavailability
例如,我们希望在2019-06-20到2019-07-05期间可用的用户:Marc和Elise可用。
我必须使用LEFT JOIN吗?该请求无效:
+------+-----------+--------------+--------------+
| id | user_id | start | end |
+------+-----------+--------------+--------------+
| 1 | 13 | 2019-07-01 | 2019-07-10 |
| 2 | 13 | 2019-07-20 | 2019-07-30 |
| 3 | 13 | 2019-09-01 | 2019-09-30 |
| 4 | 44 | 2019-08-01 | 2019-08-15 |
+------+-----------+--------------+--------------|
结果我需要:
SELECT DISTINCT user.*, unavailability.start, unavailability.end,
FROM user
LEFT JOIN unavailability ON unavailability.user_id = user.id
WHERE
unavailability.start < "2019-06-20" AND unavailability.end > "2019-06-20"
AND unavailability.start < "2019-07-05" AND unavailability.end > "2019-07-05"
有了这个请求,我不会遇到没有空闲时间段的Elise。
答案 0 :(得分:2)
DROP TABLE IF EXISTS user;
CREATE TABLE user
(id SERIAL PRIMARY KEY
,firstname VARCHAR(12) NOT NULL UNIQUE
);
INSERT INTO user VALUES
(13,'John'),
(44,'Marc'),
(55,'Elise');
DROP TABLE IF EXISTS unavailability ;
CREATE TABLE unavailability
(id SERIAL PRIMARY KEY
,user_id INT NOT NULL
,start DATE NOT NULL
,end DATE NOT NULL
);
INSERT INTO unavailability VALUES
(1,13,'2019-07-01','2019-07-10'),
(2,13,'2019-07-20','2019-07-30'),
(3,13,'2019-09-01','2019-09-30'),
(4,44,'2019-08-01','2019-08-15');
SELECT x.*
FROM user x
LEFT
JOIN unavailability y
ON y.user_id = x.id
AND y.start <= '2019-07-05'
AND y.end >= '2019-06-20'
WHERE y.id IS NULL;
+----+-----------+
| id | firstname |
+----+-----------+
| 44 | Marc |
| 55 | Elise |
+----+-----------+
2 rows in set (0.01 sec)
答案 1 :(得分:2)
可以使用这种方法:
select * from user k
where not exists (
select 1 from user
join unavailability u on u.user_id = user.id
and ('2019-06-20' between start and end or '2019-07-05' between start and end)
where user.id = k.id)
答案 2 :(得分:1)
您可以选择不可用的ID,并在子查询中使用此结果:
模式(MySQL v5.7)
CREATE TABLE user (
`id` INTEGER,
`firstname` VARCHAR(5),
`content` VARCHAR(3)
);
INSERT INTO user
(`id`, `firstname`, `content`)
VALUES
(13, 'John', '...'),
(44, 'Marc', '...'),
(55, 'Elise', '...');
CREATE TABLE unavailability (
`id` INTEGER,
`user_id` INTEGER,
`start` DATETIME,
`end` DATETIME
);
INSERT INTO unavailability
(`id`, `user_id`, `start`, `end`)
VALUES
(1, 13, '2019-07-01', '2019-07-10'),
(2, 13, '2019-07-20', '2019-07-30'),
(3, 13, '2019-09-01', '2019-09-30'),
(4, 44, '2019-08-01', '2019-08-15');
查询#1
SELECT *
FROM user us
WHERE us.id NOT IN (
SELECT u.user_id
FROM unavailability u
WHERE u.start <= '2019-07-05' AND u.end >= '2019-06-20'
);
| id | firstname | content |
| --- | --------- | ------- |
| 44 | Marc | ... |
| 55 | Elise | ... |
注意
这种情况:
unavailability.start < 2019-06-20 AND unavailability.end > 2019-06-20
AND unavailability.start < 2019-07-05 AND unavailability.end > 2019-07-05
将被这样评估:
unavailability.start < 2019-06-20 AND unavailability.end > 2019-07-05
因为对于部分unavailability.start < 2019-06-20 AND unavailability.start < 2019-07-05
,2019-07-05
以下但2019-06-20
以上的所有内容都将被排除(您正在使用AND
)。 unavailability.end