我在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/