SQL 从列表中删除结果
SQL remove results from list
我有一个位置 table 和一个访问 table。每个地点都需要根据特定的访问类型每年访问一次。当我们记录一次访问时,我们会添加访问类型和访问地点(日期时间和所有其他内容)。我需要从我们收集的信息中推断出那些没有去过的地方。
例如,位置 A-Z(26 个位置)可以有 3 种类型的访问(会议、审查和年度)。
有些地点可能根本不会被访问,而其他地点可能会被访问不止一次。
我需要知道哪些地点没有进行年度访问。
我的 SQL 声明似乎给了我一份每年访问过的地点的列表,但我看不到从较大列表中删除该条目或可能过滤较大条目的方法列表 .
SELECT
Location.Name
,Location.ID
,Visit.Date
,Visit.Time
,Visit.Visit_Type
FROM Location
INNER JOIN Visit
ON Location.ID = Visit.LocationID
WHERE Visit.Group_Type = 'School'
AND ( Visit.Date BETWEEN '2021' AND '2022' )
架构 (MySQL v8.0)
CREATE TABLE location (
`name` VARCHAR(8),
`id` INTEGER
);
INSERT INTO location
(`name`, `id`)
VALUES
('here', '1'),
('there', '2'),
('anywhere', '3');
CREATE TABLE visit (
`id` INTEGER,
`type` VARCHAR(7)
);
INSERT INTO visit
(`id`, `type`)
VALUES
('1', 'meeting'),
('1', 'review'),
('2', 'meeting'),
('2', 'annual'),
('3', 'annual');
无年检
SELECT name
FROM location
JOIN visit
USING(id)
GROUP BY name
HAVING COUNT(CASE WHEN type = 'annual' THEN 1 END) = 0;
name
here
一种方法是检查是否缺少年度,使用 EXISTS 语句访问。
SELECT
L.Name, L.ID
FROM
Location L
WHERE
NOT EXISTS
(
SELECT
*
FROM
Visit V2
WHERE
V2.LocationID = L.LocationID
AND V2.Group_Type = 'School'
AND ( V2.Date BETWEEN '2021' AND '2022' )
)
你可以获得今年所有访问的列表,然后使用 OUTER JOIN 查找今年尚未访问的位置。
;WITH visitsThisYear AS
(
SELECT
*
FROM
Visit
WHERE
Visit.Group_Type = 'School'
AND ( Visit.Date BETWEEN '2021' AND '2022' )
),
SELECT
Location.Name,
Location.ID
FROM
LOCATION
LEFT OUTER JOIN visitsThisYear
ON Location.ID = visitsThisYear.LocationID
WHERE Location.ID IS NULL
我有一个位置 table 和一个访问 table。每个地点都需要根据特定的访问类型每年访问一次。当我们记录一次访问时,我们会添加访问类型和访问地点(日期时间和所有其他内容)。我需要从我们收集的信息中推断出那些没有去过的地方。
例如,位置 A-Z(26 个位置)可以有 3 种类型的访问(会议、审查和年度)。
有些地点可能根本不会被访问,而其他地点可能会被访问不止一次。
我需要知道哪些地点没有进行年度访问。
我的 SQL 声明似乎给了我一份每年访问过的地点的列表,但我看不到从较大列表中删除该条目或可能过滤较大条目的方法列表 .
SELECT
Location.Name
,Location.ID
,Visit.Date
,Visit.Time
,Visit.Visit_Type
FROM Location
INNER JOIN Visit
ON Location.ID = Visit.LocationID
WHERE Visit.Group_Type = 'School'
AND ( Visit.Date BETWEEN '2021' AND '2022' )
架构 (MySQL v8.0)
CREATE TABLE location (
`name` VARCHAR(8),
`id` INTEGER
);
INSERT INTO location
(`name`, `id`)
VALUES
('here', '1'),
('there', '2'),
('anywhere', '3');
CREATE TABLE visit (
`id` INTEGER,
`type` VARCHAR(7)
);
INSERT INTO visit
(`id`, `type`)
VALUES
('1', 'meeting'),
('1', 'review'),
('2', 'meeting'),
('2', 'annual'),
('3', 'annual');
无年检
SELECT name
FROM location
JOIN visit
USING(id)
GROUP BY name
HAVING COUNT(CASE WHEN type = 'annual' THEN 1 END) = 0;
name |
---|
here |
一种方法是检查是否缺少年度,使用 EXISTS 语句访问。
SELECT
L.Name, L.ID
FROM
Location L
WHERE
NOT EXISTS
(
SELECT
*
FROM
Visit V2
WHERE
V2.LocationID = L.LocationID
AND V2.Group_Type = 'School'
AND ( V2.Date BETWEEN '2021' AND '2022' )
)
你可以获得今年所有访问的列表,然后使用 OUTER JOIN 查找今年尚未访问的位置。
;WITH visitsThisYear AS
(
SELECT
*
FROM
Visit
WHERE
Visit.Group_Type = 'School'
AND ( Visit.Date BETWEEN '2021' AND '2022' )
),
SELECT
Location.Name,
Location.ID
FROM
LOCATION
LEFT OUTER JOIN visitsThisYear
ON Location.ID = visitsThisYear.LocationID
WHERE Location.ID IS NULL