检查结果中的双打,如果有 none,则删除另一个 table 中的行

Check for doubles in results and then delete row in another table if there are none

我想创建一个执行以下操作的复杂查询

得到 laptop, service, technician of table lst according to laptop equals X (number)

在您获得的这些行中,删除 laptop(实际上无法删除,因此将其设为 null

相同的行,也许有些没有 technician。所以它们是现在仅包含 service 的行,没有 laptop 也没有 technician

棘手的部分:保留这些行的所有 service
如果在 lst table 的其他任何地方都找不到它们,正在与其他 laptoptechnician 配对,则转到 service table 和删除该行。然后返回 lst 并删除所有具有 service 且没有 laptoptechnician 的行。
如果它们在 lst table 的其他任何地方被发现,与其他 laptoptechnician 配对,则只需删除 lst 中的所有 lst 行] 有 service 而没有 laptoptechnician

示例

lst table
laptop service technician 
17     10      25
17     10      26
17      4      null
17      2      null
125     2      null

我们通过 laptop = 17

来执行上面的操作

变成

laptop service technician 
null     10      25
null     10      26
null      4      null
null      2      null
125       2      null

必须删除第 3 行,因为它没有 technicianlaptop。此外, table serviceservice 4 必须删除,因为在 lts table 中找不到其他任何地方,与任何东西配对.

必须删除第 4 行,因为它没有 technicianlaptop。但是 table serviceservice 2 不会被删除,因为它在 lts 的其他地方找到,与另一个 laptop (最后一行)配对

所以,lts 现在变成了

laptop service technician 
null     10      25
null     10      26
125       2      null

而且我只删除了 service 4 个 service table

我试过几种queries/subqueries组合,比如

select id , technician from lts where  laptop= 17 and  technician in(
  select id   from 
  lts 
  where id in
    (select id from lts where technician is null and  laptop = 17) 
);

但是没有任何效果,也没有任何东西可以保留所有 ID,稍后再从 service table 中删除。

我想我将不得不使用 pl/pgsql 函数或交易,但即使有了交易,我也不知道如何简单地保存任何 ID 以便以后从 service [=100] 中删除=].

有什么办法吗?策略还是基本代码?

我使用 postgresql 10

谢谢

您可以像这样使用 CTE 来存储中间结果并在一个查询中执行多个更新操作。

查询看起来像这样(演示想法 - 未测试):

WITH potentially_orphan_services AS (
    SELECT service
    FROM lts
    WHERE laptop = X AND technician IS NULL
), deleted_services AS (
    DELETE FROM services
    WHERE service IN (
       SELECT service
       FROM potentially_orphan_services p
       WHERE NOT EXIST (
         SELECT 1
         FROM lts l
         WHERE laptop != X AND l.service = p.service
       )
), deleted_lts_without_technician AS (
   DELETE FROM lts
   WHERE laptop = X AND technician IS NULL
)
UPDATE lts
SET laptop = NULL
WHERE laptop = X AND technician IS NOT NULL