SQL Выберите Условие Вопрос - PullRequest
       15

SQL Выберите Условие Вопрос

1 голос
/ 18 декабря 2009

У меня быстрый вопрос по условию выбора оператора.

У меня есть следующая таблица со следующими пунктами. Мне нужно получить идентификатор объекта, который совпадает с идентификаторами обоих типов.

TypeId  ObjectId
1       10
2       10
1       11

Так что мне нужно получить оба объекта 10, потому что они соответствуют типу id 1 и 2.

SELECT ObjectId
FROM Table
WHERE TypeId = 1
AND TypeId = 2

Очевидно, что это не работает, потому что не будет соответствовать обоим условиям для одной и той же строки. Как мне выполнить этот запрос? Также обратите внимание, что я могу передать 2 или более идентификатора типа, чтобы сузить результаты.

Ответы [ 4 ]

5 голосов
/ 18 декабря 2009

автообъединение:

SELECT t1.ObjectId 
FROM Table AS t1
INNER JOIN Table AS t2
    ON t1.ObjectId = t2.ObjectId
    AND t1.TypeId = 1 
    AND t2.TypeId = 2 

Обратите внимание, что вы хотите, чтобы поведение работало при передаче значений, но это только начало.

3 голосов
/ 18 декабря 2009

Я проголосовал за ответ от @Cade Roux, и вот как бы я это сделал.

Но, FWIW, вот альтернативное решение:

SELECT ObjectId
FROM Table
WHERE TypeId IN (1, 2)
GROUP BY ObjectId
HAVING COUNT(*) = 2;

Предполагая уникальность свыше TypeId, ObjectId.


Относительно комментария @Josh ему может потребоваться поискать три или более TypeId значений:

Решение, использующее JOIN, требует объединения для каждого значения, которое вы ищете. Приведенное выше решение с использованием GROUP BY может оказаться проще, если вы обнаружите, что ищете все большее число значений.

1 голос
/ 18 декабря 2009

Этот код написан для Oracle. Он должен быть достаточно общим для других разновидностей SQL

select t1.ObjectId from Table t1
join Table t2 on t2.TypeId = 2 and t1.ObjectId = t2.ObjectId
where t1.TypeId = 1;

Чтобы добавить дополнительные TypeIds, вам просто нужно добавить еще одно объединение:

select t1.ObjectId from Table t1
join Table t2 on t2.TypeId = 2 and t1.ObjectId = t2.ObjectId
join Table t3 on t3.TypeId = 3 and t1.ObjectId = t3.ObjectId
join Table t4 on t4.TypeId = 4 and t1.ObjectId = t4.ObjectId
where t1.TypeId = 1;

Важное замечание: по мере добавления новых объединений производительность будет сильно снижаться.

Что касается ответа Билла, вы можете изменить его на следующий, чтобы избавиться от необходимости предполагать уникальность:

SELECT ObjectId
FROM (SELECT distinct ObjectId, TypeId from Table)
WHERE TypeId IN (1, 2)
GROUP BY ObjectId
HAVING COUNT(*) = 2;

Его способ сделать это лучше масштабируется по мере увеличения числа типов.

0 голосов
/ 19 декабря 2009

Попробуйте это

Пример ввода: (Случай 1)

declare @t table(Typeid int,ObjectId int)
insert into @t 
    select 1,10 union all select 2,10  union all    
    select 1,11 
select * from @t 

Пример ввода: (Случай 2)

declare @t table(Typeid int,ObjectId int)
insert into @t 
    select 1,10 union all select 2,10  union all 
    select 3,10 union all select 4,10  union all 
    select 5,10 union all select 6,10  union all 
    select 1,11 union all select 2,11  union all 
    select 3,11 union all select 4,11  union all 
    select 5,11 union all select 1,12  union all 
    select 2,12  union all select 3,12 union all 
    select 4,12  union all select 5,12 union all 
    select 6,12  
select * from @t

Пример ввода: (Случай 3) [Дубликаты записей есть]

declare @t table(Typeid int,ObjectId int)
insert into @t 
    select 1,10 union all select 2,10  union all 
    select 1,10 union all select 2,10 union all
    select 3,10 union all select 4,10  union all 
    select 5,10 union all select 6,10  union all 
    select 1,11 union all select 2,11  union all 
    select 3,11 union all select 4,11  union all 
    select 5,11 union all select 1,12  union all 
    select 2,12  union all select 3,12 union all 
    select 4,12  union all select 5,12 union all 
    select 6,12  union all select 3,12 

Для случая 1 вывод должен быть 10

Для случаев 2 и 3 выходное значение должно быть 10 и 12

Запрос:

select X.ObjectId from 
(
select 
            T.ObjectId
            ,count(ObjectId) cnt
from(select distinct ObjectId,Typeid from @t)T
where T.Typeid in(select Typeid from @t)
group by T.ObjectId )X
join (select max(Typeid) maxcnt from @t)Y
on X.cnt = Y.maxcnt
...