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

Откуда: From Russia
Сообщений: 146
Всем привет,
Есть хранимка, которая принимает входные данные в виде таблицы, например:
автор
Number, ID
1, 345
1, 9872
2, 234
3, 989
4, 4322
4, 489
4, 32809

Здесь Number - это номер заказа, ID - идшник конкретного товара
Хранимка должны выбрать данные для каждого ID'шника в рамках каждого заказа, и вернуть результат, что-то вроде: Номер заказа, плюс различные данные по заказу.
Для простоты представим, что нужно выполнить простой запрос. Для одного заказа он выглядел бы так
select * from Orders where ProductID in (345, 9872)

Вот, а как написать запрос, чтобы выдерннул данные для всех заказов?
На вход пришла таблица
declare @data table(Number int, ID bigint)

И надо здесь как-то сгруппировать по Number, и в рамках каждой группы выполнить
select * from Orders where ProductID in (345, 9872)

Т.е. получается только в цикле для каждого заказа вызвать этот запрос? Или можно проще?
12 янв 12, 17:01    [11893927]     Ответить | Цитировать Сообщить модератору
 Re: Как написать такой запрос  [new]
Knyazev Alexey
Member

Откуда: Екб -> Мск
Сообщений: 10233
Блог
select d.Number, o.* from Orders o inner join @data d on o.ProductID = d.id
12 янв 12, 17:07    [11893995]     Ответить | Цитировать Сообщить модератору
 Re: Как написать такой запрос  [new]
Kudep
Member

Откуда: From Russia
Сообщений: 146
Knyazev Alexey
select d.Number, o.* from Orders o inner join @data d on o.ProductID = d.id

ничего не понимаю. А если в таблице Orders будет лежать два заказа на ProductID = 345, два заказа на ProductID = 9872, и только один, который содержит и 345 и 9872, в этом случае только его одного надо вернуть.
12 янв 12, 17:32    [11894268]     Ответить | Цитировать Сообщить модератору
 Re: Как написать такой запрос  [new]
Knyazev Alexey
Member

Откуда: Екб -> Мск
Сообщений: 10233
Блог
Kudep
Knyazev Alexey
select d.Number, o.* from Orders o inner join @data d on o.ProductID = d.id

ничего не понимаю. А если в таблице Orders будет лежать два заказа на ProductID = 345, два заказа на ProductID = 9872, и только один, который содержит и 345 и 9872, в этом случае только его одного надо вернуть.


почему не нужно возвращать 2 первых заказа?

сформулируйте задачу более внятно
12 янв 12, 17:35    [11894303]     Ответить | Цитировать Сообщить модератору
 Re: Как написать такой запрос  [new]
--__Александр__--
Member

Откуда:
Сообщений: 2631
Вас очень сложно понять.
Представьте скрипт создания таблиц и заполнения их тестовыми данными и что нужно получить.
12 янв 12, 17:36    [11894310]     Ответить | Цитировать Сообщить модератору
 Re: Как написать такой запрос  [new]
Knyazev Alexey
Member

Откуда: Екб -> Мск
Сообщений: 10233
Блог
Knyazev Alexey
Kudep
пропущено...

ничего не понимаю. А если в таблице Orders будет лежать два заказа на ProductID = 345, два заказа на ProductID = 9872, и только один, который содержит и 345 и 9872, в этом случае только его одного надо вернуть.


почему не нужно возвращать 2 первых заказа?

сформулируйте задачу более внятно


ваш запрос:
select * from Orders where ProductID in (345, 9872)

вернет все 3 заказа
12 янв 12, 17:37    [11894318]     Ответить | Цитировать Сообщить модератору
 Re: Как написать такой запрос  [new]
Kudep
Member

Откуда: From Russia
Сообщений: 146
Допустим вот рабочие таблицы:
declare @product_order table(WordID bigint, NumWord int, QueryID bigint)
insert into @product_order values(1001,3,1),(1002,3,1),(1003,3,1)
declare @order table(ID bigint, NumTransitions int)
insert into @order values(1, 102),(2, 202),(3, 302),(4, 402)


Вот такой запрос у меня уже был, и он долгое время нормально работал, так что с ним всё ок.
select top 1 q.* 
from ( 
	select QueryID from @product_order wq 
	where wq.WordID in (1001,1002,1003) and wq.NumWord = 3 group by QueryID 
	having count(*) = 3) wq 
inner loop join  @order q 
on q.ID = wq.QueryID 
order by NumTransitions desc 

Это запрос принимает на вход значения, относящиеся только к одному Order. Я хочу переделать этот запрос, чтобы он принимал пачки товаров, относящихся к разным Order.
Попробовал по совету переписать его так:
declare @wordIDs table ([Number] [int] NOT NULL, [WordID] bigint NOT NULL, [WordsCount] [int] NOT NULL)
insert into @wordIDs
values(1, 1001, 3),(1, 1002, 3),(1, 1003, 3)
select top 1 wq.Number, q.* 
from ( 
	select wi.Number, QueryID from @product_order wq 
	join @wordIDs wi on wi.WordID = wq.WordID and wi.WordsCount = wq.NumWord
	group by QueryID, wi.WordsCount, wi.Number
	having count(*) = wi.WordsCount) wq 
inner loop join @order q 
on q.ID = wq.QueryID 
order by NumTransitions desc 

Вроде бы тоже самое. Только вместо конкретных трех значений ID (1001,1002,1003), здесь теперь может быть целая таблица @wordIDs, в которой Number - это некий логический номер заказа, WordID - идшник товара в данном заказе, WordsCount - число товаров в данном заказе.
И это работает!!!
Только вот на базе с очень большим количеством записей второй вариант запроса работает гораздо медленней первого, минута против 2 секунд.
13 янв 12, 09:53    [11897135]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить