2013-04-01 5 views
0

У меня есть следующая таблица - Task(id, type, sessionId, termination, scenario) У меня есть список sessionId.Выделить все элементы из групп

Я хотел бы выбрать все задачи, общие для этих сеансов. Задачи равны, если они имеют один и тот же тип, завершение и сценарий.

Пример -

| id | type | sessionId | termination | scenario | 
    1  A   20  duration  sc1 
    2  B   20  invocation  sc1 
    3  C   20  duration  sc2 
    4  A   21  duration  sc1 
    5  B   21  invocation  sc1 

Для sessionId списка равен (20, 21) - Я хотел бы получить следующую информацию

| id | type | sessionId | termination | scenario | 
    1  A   20  duration  sc1 
    2  B   20  invocation  sc1 
    4  A   21  duration  sc1 
    5  B   21  invocation  sc1 

Задача с идентификаторами = 1,2,4,5 является общим для сессий 20 и 21.

Я разрабатываю следующий запрос -

select l.* from Task l 
inner join(select p.* from Task p 
      where 
       p.sessionId in (20,21) 
      group by 
        p.type, 
        p.termination, 
        p.scenario 
      having 
        count(p.id)=2)s 
on 
    l.type=s.type 
    and l.scenario=s.scenario 
    and l.termination=s.termination; 

Это лучший способ получить такую ​​информацию? Может быть, есть лучший запрос, который содержит только одну операцию select и работает быстрее?

ответ

0

Вот такой подход. Найдите все пары для ввода, завершения и сценария, которые соответствуют всем сеансам. Тогда присоединяйтесь обратно в tasks таблице, чтобы получить всю информацию:

select t.* 
from tasks t join 
    (select type, termination, Scenario 
     from tasks 
     where sessionId in (20, 21) 
     group by type, termination, scenario 
     having count(distinct sessionId) = 2 
    ) tts 
    on tts.type = t.type and tts.termiantion = t.termination and tts.scenario = t.scenario 
where t.sessionId in (20, 21); 

Вы должны изменить список и 2 (если вы измените размер списка).

+0

Это хорошее решение! Но есть ли способ не использовать 2 операции «выбрать»? –

0

Мой нижний код не ограничивает какой-либо конкретный поднабор sessionID.

SELECT t1.* 
FROM Task AS t1 INNER JOIN Task AS t2 ON t1.type = t2.type AND t1.termination = t2.termination AND 
            t1.scenario = t2.scenario AND t1.sessionid <> t2.sessionid AND 
            t1.id <> t2.id 
ORDER BY t1.id 

Вот SQL Fiddle: http://sqlfiddle.com/#!2/55d7c/9 Не стесняйтесь экспериментировать.

Я несколько неправильно понял ваши требования?

+0

Ваше решение зависит от размера списка sessionId. Это может быть более двух сеансов) –

+0

Мое намерение состояло в том, чтобы построить запрос, который не зависит от количества сеансов: искать все, что ** соответствует ** 3 ключевым полям и ** не совпадать ** 'id' и 'sessionid'. Это неправильный подход? –

+0

Вы можете добавить 'AND t1.sessionid IN (20, 21) И t2.sessionid IN (20, 21)'. Если у вас несколько идентификаторов сеанса, тогда вам нужно будет в любом случае добавить «GROUP BY», и может быть, ваш исходный запрос будет быстрее. (Но сначала вы должны профилировать.) – Neil

Смежные вопросы