2014-09-03 3 views
1

я получил следующую таблицу в базе данных Postgres:JOIN с помощью отрицания положения

Таблица Пример:

--------------------------- 
    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 

мне нужно, чтобы получить «число» S, которые присутствуют в " 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' 
+1

Определить «отсутствует». Те, которые отсутствуют между минимальным и максимальным значением имени или общего или некоторого заданного значения min/max? Или просто цифры отображаются с «DefaultName»? –

+0

Нет, это не имеет никакого отношения к заказу или значениям max/min. Он имеет отношение к значениям, которые присутствуют в DefaultName, но не в других именах. – ZeldaElf

+0

Я изменил свои заявления, возможно, я сделал себя немного яснее. – ZeldaElf

ответ

3

Я бы генерировать весь диапазон одного имени и 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.

Вот основные методы, чтобы исключить строки, существующие в другой таблице (производные таблицы в этом примере):

+0

Я не получаю эти значения, которые я намеревался в сообщении ... Я думаю, что, возможно, оператор LEFT JOIN не работает хорошо, поскольку цифры не наступают ... – ZeldaElf

+1

@ZeldaElf: Это странно, потому что я получаю результат, который вы показали: http://sqlfiddle.com/#!15/8aa67/1 и 'LEFT JOIN' должны работать очень хорошо. Существуют ли какие-либо значения «NULL»? Или все столбцы определены 'NOT NULL'. –

+0

Извините, друг. Простите, я видела ошибку в моих вставках, прошу прощения. Это сработало! Но я все еще не могу понять, как вы это сделали с CROSS. Я немного поучусь об этом. Большое спасибо! – ZeldaElf

2

It займет несколько проходов, выберите значение по умолчанию, имена групп, которые не являются по умолчанию, затем левое соединение и проверьте нулевые значения. Проверьте пример SQLFiddle.

select Names.name, DefaultConfigs.number 
from Example DefaultConfigs 
    cross join (
    select name 
    from Example 
    where name != 'DefaultName' 
    group by name 
    ) Names 
    left join Example Missing on Missing.name = Names.name 
    and Missing.number = DefaultConfigs.number 
where DefaultConfigs.name = 'DefaultName' 
    and Missing.name is null 
; 
+0

Это тоже сработало, мой друг! Спасибо, что зашли! – ZeldaElf

1

Постройте все комбинации имени и номера по умолчанию. Затем удалите присутствующие.

select othernames.name, defaultnumbers.number 
from (select number from example where name = 'DefaultName') defaultnumbers 
cross join (select distinct name from example where name <> 'DefaultName') othernames 
except 
select name, number from example; 
Смежные вопросы