Xpoint
   [напомнить пароль]

Intersect / Except используя With MSSQL2005

Метки: [без меток]
2007-06-13 21:19:42 [обр] 4eburek[досье]

Такая проблема: нужно выбрать все, кроме пересечения двух множеств.
Такого оператора я не знаю. Решение может быть таким:

 WITH S1 as (
      SELECT   [name]   FROM T1 WHERE [number]=1
   ), S2 as (
      SELECT   [name]   FROM T1 WHERE [number]=2
   )
   
   SELECT count(*) FROM  (S1 UNION S2) EXCEPT (S2 Intersect S1)

либо

   SELECT count(*) FROM  (S1 EXCEPT S2) UNION (S2 EXCEPT S1)

Но! Вот такая форма записи не работает! Ругается, мол не такая форма записи возле Uniun или Except соответственно.

Я пытался записать так

   SELECT count(*) FROM  (
           SELECT   [name]   FROM T1 WHERE [number]=1 
        UNION 
           SELECT   [name]   FROM T1 WHERE [number]=2
        ) EXCEPT (
           SELECT   [name]   FROM T1 WHERE [number]=2 
        Intersect 
           SELECT   [name]   FROM T1 WHERE [number]=1)

В этом случае ругается, что не так что-то записано возле EXCEPT
Помогите плз!

спустя 1 час 20 минут [обр] Евгений[досье]
Я знаю что в случае MySQL обычно просто добавляют условие
WHERE S1.param = S2.param, где param - любое общее поле для двух таблиц.
При этом мы можем получить пересечение, а в случае " != "(IS NOT) - наоборот.
спустя 13 часов [обр] 4eburek[досье]
это немножко не тот случай. В принципе, если извращнуться, может быть и есть возможность записать в таком виде, но значительно потеряется наглядность и удобочитаемость кода.
Дело в том, что мне нужно выбрать строки, которые были изменены, сравнительно с предыдущей записанной версией, т.е. если хотя бы одно из выбираемых полей (в указанном мною примере это просто [name]) изменилось, то оно должно попасть в выборку. Туда же должны попасть строки, которые были либо удалены из предыдущей версии, либо были добавлены. Фактически меня вообще интересует только наличие оного. Т.е. если в выборке есть хоть один элемент, то я уже доволный :)
спустя 28 минут [обр] 4eburek[досье]
Заработало вот так, с With все-равно не канает:
        SELECT * FROM (
      SELECT   [name]   FROM T1 WHERE [number]=1                   
   UNION
      SELECT   [name]   FROM T1 WHERE [number]=2
   ) as t1   
   EXCEPT 
   SELECT * FROM (
      SELECT   [name]   FROM T1 WHERE [number]=1                      
   INTERSECT      
      SELECT   [name]   FROM T1 WHERE [number]=2   
   ) as t2
спустя 19 минут [обр] Евгений[досье]

Может быть дело в том, что в базе настройки такие, что нельзя открывать несколько сессий одновременно?

Вот что я нашёл на Dev MySQL:

Database user MONA has been created in the DEMODB demo database instance as a database administrator (DBA) with the password RED. The database administrator MONA can open several database sessions at once (NOT EXCLUSIVE).

А вот описание операторов INTERSECT|UNION|EXCEPT:
Set Operations
Судя по всему, проблема не в самом запросе, а именно в настройках базы.

спустя 15 минут [обр] 4eburek[досье]
Хм, может быть. Во всяком случае, на базу я влиять не могу. Вот чего у меня получилось - final
Больше ничего не знаю и не могу. Спасибо, тему можна закрывать
   WITH S11 as (   
         SELECT
            Alias, 
            OfferTypeId,
            Description, Ordinal
         FROM Items
            WHERE Num = @Num and Rev = @Rev    
   ), S22 as (
         SELECT
            Alias, 
            OfferTypeId,
            Description, Ordinal
         FROM Items
            WHERE Num = @Num and Rev = @Rev2
   ), S1 as (   
         -- S1 - All items from two revisions            
         SELECT * FROM S11 UNION SELECT * FROM S22            
   ), S2 as (
         -- S2 - Identical items from two revisions
         SELECT * FROM S11 INTERSECT SELECT * FROM S22                     
   )
      
   SELECT * FROM S1 EXCEPT SELECT * FROM S2
Powered by POEM™ Engine Copyright © 2002-2005