Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Правильный INTERSECT для нескольких SELECT  [new]
webness
Member

Откуда:
Сообщений: 32
Здравствуйте.

Есть, в общем-то, тривиальная задача.

Имеем несколько списков, нужно получить пересечение этих списков.

Как было раньше: делалось N запросов к базе (к одной таблице) с разными условиями,
получали оттуда списки, а потом пересекали их уже в коде (типа list.Intersect(list2)).

Подумалось: почему бы не переложить это на SQL Server?

SELECT Id FROM Table WHERE (_условия_)
INTERSECT
SELECT Id FROM Table WHERE (_условия_)
INTERSECT
SELECT Id FROM Table WHERE (_условия_)
INTERSECT
SELECT Id FROM Table WHERE (_условия_)
INTERSECT
SELECT Id FROM Table WHERE (_условия_)
INTERSECT
SELECT Id FROM Table WHERE (_условия_)
......

При таком запросе вылазит:
The query processor ran out of internal resources and could not produce a query plan. 
This is a rare event and only expected for extremely complex queries or queries that reference
a very large number of tables or partitions.

Для моей задачи надо сделать ровно столько запросов, сколько SELECT, причем простых очень,
а потом пересечь массивы чисел.

SQL Server, по видимости, делает не так.

Как правильно написать такой запрос?
8 фев 11, 21:43    [10204657]     Ответить | Цитировать Сообщить модератору
 Re: Правильный INTERSECT для нескольких SELECT  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
SELECT Id FROM Table WHERE (_условия_) AND (_условия_) AND (_условия_) AND (_условия_) AND (_условия_)....
8 фев 11, 21:55    [10204729]     Ответить | Цитировать Сообщить модератору
 Re: Правильный INTERSECT для нескольких SELECT  [new]
webness
Member

Откуда:
Сообщений: 32
iap, извиняюсь, неточно поставил задачу.

_условия_, они такие, к примеру:

SELECT Id FROM Table WHERE (IdCall = 5) AND (IdFix = 10)
INTERSECT
SELECT Id FROM Table WHERE (IdCall = 6) AND (IdFix = 10)
INTERSECT
SELECT Id FROM Table WHERE (IdCall = 7) AND (IdFix = 10)
INTERSECT
SELECT Id FROM Table WHERE (IdCall = 8) AND (IdFix = 10)
INTERSECT
SELECT Id FROM Table WHERE (IdCall = 9) AND (IdFix = 10)
INTERSECT
SELECT Id FROM Table WHERE (IdCall = 10) AND (IdFix = 10)
......

OR использовать нельзя: так как будут выбраны Id для каких-либо из списка IdCall, а нужны те,
для которых существуют все IdCall.
8 фев 11, 22:21    [10204862]     Ответить | Цитировать Сообщить модератору
 Re: Правильный INTERSECT для нескольких SELECT  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31983
webness
OR использовать нельзя: так как будут выбраны Id для каких-либо из списка IdCall, а нужны те,
для которых существуют все IdCall.

Если Id для сочетаний IdCall и IdFix уникальные, то:
SELECT Id, count(*) 
FROM Table 
WHERE 
(IdCall = 5) AND (IdFix = 10)
or
(IdCall = 7) AND (IdFix = 10)
or
(IdCall = 8) AND (IdFix = 10)
or
(IdCall = 9) AND (IdFix = 10)
or
(IdCall = 10) AND (IdFix = 10)
group by Id
having count(*) = 5
8 фев 11, 22:40    [10204949]     Ответить | Цитировать Сообщить модератору
 Re: Правильный INTERSECT для нескольких SELECT  [new]
iljy
Member

Откуда:
Сообщений: 8711
webness,

вариантов масса. Самый простой ИМХО
SELECT Id FROM Table WHERE IdFix = 10
   AND IdCall in (5,6,7,8,9,10,...)
GROUP BY Id
HAVING COUNT(*) = количество разных IdCall
возможны варианты, в зависимости от условий, индексов и т.д.
9 фев 11, 00:33    [10205252]     Ответить | Цитировать Сообщить модератору
 Re: Правильный INTERSECT для нескольких SELECT  [new]
webness
Member

Откуда:
Сообщений: 32
alexeyvg, iljy

Id для сочетаний IdCall и IdFix не уникальны.

Вот, что у меня получилось:
SELECT fv.Id FROM (

	SELECT Id, IdCall FROM Table
	WHERE 
	AND IdFix = 10
           .......

	AND IdCall IN (1, 2, 3, 4)           

	GROUP BY IdResp, IdCall
) AS fv

GROUP BY Id
HAVING COUNT(*) = 4

Вроде работает и вроде правильно :)

Но не нравится вложенный запрос. Или это нормально для такой ситуации?
9 фев 11, 12:11    [10207155]     Ответить | Цитировать Сообщить модератору
 Re: Правильный INTERSECT для нескольких SELECT  [new]
1
Guest
А как насчет
SELECT ID
FROM ((SELECT Id FROM Table WHERE (IdCall = 5) AND (IdFix = 10)
INTERSECT
SELECT Id FROM Table WHERE (IdCall = 6) AND (IdFix = 10)) t
INTERSECT
SELECT Id FROM Table WHERE (IdCall = 7) AND (IdFix = 10)) t1
INTERSECT
SELECT Id FROM Table WHERE (IdCall = 8) AND (IdFix = 10)
.......
9 фев 11, 13:41    [10208084]     Ответить | Цитировать Сообщить модератору
 Re: Правильный INTERSECT для нескольких SELECT  [new]
webness
Member

Откуда:
Сообщений: 32
По-моему, это ничем не отличается от того, что в первом посте — те же множественные селекты и интерсекты,
и на них сервер выдает ошибку, что, мол, сложный запрос.
9 фев 11, 14:40    [10208631]     Ответить | Цитировать Сообщить модератору
 Re: Правильный INTERSECT для нескольких SELECT  [new]
1
Guest
Ну тогда используйте временные таблицы и делайте выборку по ним
9 фев 11, 16:32    [10209626]     Ответить | Цитировать Сообщить модератору
 Re: Правильный INTERSECT для нескольких SELECT  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
1
Ну тогда используйте временные таблицы и делайте выборку по ним
В цикле по курсору
9 фев 11, 16:41    [10209703]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Правильный INTERSECT для нескольких SELECT  [new]
like_you
Member

Откуда:
Сообщений: 3
Интересно, а JOIN с этой мега-задачей не справляется? Или нужна уникальность, а вы не знали про DISTINCT?
18 фев 12, 21:14    [12116578]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить