Достаточно ли использовать где-нибудь дважды на столе с композитным ПК? - PullRequest
3 голосов
/ 15 декабря 2011

У меня есть запрос

SELECT * 
FROM table1
WHERE
documentId in
(
   --select items from a second table where a third column happens to be null
   select documentId from table2 t2 inner join table1 t1
   on t1.documentId = t2.documentId and t1.itemId = t2.ItemId
   WHERE t1.someOtherColumn is null
)
and itemId in
(
   --similar query as above, just selecting itemId now
   select itemId from table2 t2 inner join table1 t1
   on t1.documentId = t2.documentId and t1.itemId = t2.ItemId
   WHERE t1.someOtherColumn is null
)
order by 1

Учитывая, что table1 имеет составной PK = documentId + itemId, достаточно ли этого для выбора только тех значений из таблицы1, которые являются уникальными? Я боюсь, что может возникнуть ситуация, когда documentId существует и itemId существует, но, поскольку они не рассматриваются вместе, могут быть сделаны неправильные выборы.

Например,

Предположим, что существует значение

documentId = 1 и itemId = 1.

Предположим, что нет составного ключа

documentId = 1 и itemId = 1.

Я не хочу составной ключ

[documentId = 1 и itemId = 3]

будет включено.

я тоже не хочу составной ключ

[documentId = 2 и itemId = 1]

будет включено.

Если позже был добавлен составной ключ (его сейчас нет)

[documentId = 1 и itemId = 1]

тогда оно должно быть включено.

Ответы [ 3 ]

5 голосов
/ 15 декабря 2011

Это сделало бы то же самое, не используя ни объединение, ни два IN s

SELECT *
FROM table1
WHERE exists
(
    SELECT 1
    FROM table2
    WHERE someOtherColumn is null
        AND table1.documentId = table2.documentId
        AND table1.itemId = table2.ItemId
)
ORDER BY 1
5 голосов
/ 15 декабря 2011

Вы правы, полагая, что это может привести к ошибочным результатам. Вы можете использовать это:

SELECT table1.* 
FROM table1
WHERE someOtherColumn IS NULL
  AND (documentId, itemId ) IN
   (
   SELECT documentId, itemId 
   FROM table2 t2                  --- no need for table1 again here 
   )
ORDER BY 1

Обновление: я думаю, что выше не работает в SQL-Server, только в Postgres (и Oracle?). В любом случае, это должно работать в большинстве систем:

SELECT table1.* 
FROM table1
WHERE someOtherColumn IS NULL
  AND EXISTS
   (
   SELECT documentId, itemId FROM table2 t2     
   WHERE table2.documentId = table1.documentId
     AND table2.itemId = table1.itemId
   )
ORDER BY 1
2 голосов
/ 15 декабря 2011

как насчет этого:

SELECT * 
FROM table1,
(
   select documentId, itemid from table2 t2 inner join table1 t1
   on t1.documentId = t2.documentId and t1.itemId = t2.ItemId
   WHERE someOtherColumn is null
) t
WHERE
table1.documentId = t.documentid
and table1.itemId = t.itemid
order by 1
...