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

View on DB Fiddle

一种方法是检查是否缺少年度,使用 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