我在Postgres数据库中有下表:
表格示例:

---------------------------
   name     |    number
---------------------------
DefaultName |       1
DefaultName |       2
DefaultName |       3
DefaultName |       4
Charlie     |       1
Charlie     |       3
Charlie     |       4
Charlie     |       5
Amanda      |       2
Amanda      |       3
Amanda      |       4
Amanda      |       5

我需要得到'DefaultName'中存在的“数字”,但是每个不同于'DefaultName'的“名称”中都不存在这些数字。
在这种情况下,它将返回:
---------------------------
   names    |    numbers
---------------------------
Charlie     |       2
Amanda      |       1

我正在尝试像下面这样的左连接,但是我想不出一种方法来让DefaultName数字与其他名称的否定号交叉。。。
SELECT Test_Configs.name, Default_Configs.number

FROM Example AS Test_Configs
    LEFT JOIN Example AS Default_Configs
        ON Default_Configs.name = 'DefaultName'

最佳答案

我将生成每个名称的整个范围,并LEFT JOIN到基表以消除当前的范围:

SELECT n.name, nr.number
FROM  (
   SELECT DISTINCT name
   FROM   example
   WHERE  name <> 'DefaultName'
   ) n                         -- all names except 'DefaultName'
CROSS  JOIN (
   SELECT number               -- assuming distinct numbers for 'DefaultName'
   FROM   example
   WHERE  name = 'DefaultName'
   ) nr                        -- combine with numbers from 'DefaultName'
LEFT   JOIN example x USING (name, number)
WHERE  x.number IS NULL;       -- minus existing ones

要单独列出每个名称的间距,请执行以下操作:
SELECT n.name, nr.number
FROM  (
   SELECT name, min(number) AS min_nr, max(number) AS max_nr
   FROM   example
   GROUP  BY 1
   ) n
 , generate_series(n.min_nr, n.max_nr) AS nr(number)
LEFT   JOIN example x USING (name, number)
WHERE  x.number IS NULL;

SQL Fiddle.
下面是排除在另一个表中存在的行的基本技术(本示例中的派生表):
Select rows which are not present in other table

关于sql - 使用否定子句进行联接,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25653592/

10-16 15:21