Может ли подзапрос SQL возвращать два или более значений, но сравнивать их с одним из них? - PullRequest
0 голосов
/ 15 мая 2009

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

SELECT Items.Name, tblBooks.AuthorLastName, tblBooks.AuthorFirstName
FROM Items WHERE Items.ProductCode IN (
SELECT TOP 10 Recommended.ProductCode
FROM 
Recommended 
INNER JOIN Stock ON Recomended.ProductCode = Stock.ProductCode
AND Stock.StatusCode = 1
WHERE (Recommended.Type = 'TOPICAL') ORDER BY CHECKSUM(NEWID()));

Это хорошо для моих данных, за исключением того, что в Рекомендованной таблице есть поле SKU, которое мне также нужно, однако я не могу поставить его рядом с Recommended.ProductCode и запрос все еще работает.
Я использовал JOINS для этого запроса, и они работают - но этот запрос выполняется быстрее. Мне просто нужны ProductCode и SKU из таблицы Recommended - как это можно сделать, не требуя еще одного подзапроса?
База данных: MS SQL Server 2000

Ответы [ 4 ]

1 голос
/ 15 мая 2009

Кажется, что подзапрос выбирает 10 случайных рекомендаций. Я думаю, что вы можете сделать это без подзапроса:

SELECT TOP 10
    Items.*,
    Recommended.*,
    Stock.*
FROM Items 
INNER JOIN Recommended 
    ON Items.ProductCode = Recommended.ProductCode
    AND Recommended.Type = 'TOPICAL'
INNER JOIN Stock 
    ON Recomended.ProductCode = Stock.ProductCode
    AND Stock.StatusCode = 1
ORDER BY CHECKSUM(NEWID())

Это дает вам доступ ко всем столбцам без необходимости передавать их из подзапроса.

0 голосов
/ 15 мая 2009

Я думаю, вам нужно переместить подзапрос из предложения where:

SELECT Items.Name, tblBooks.AuthorLastName, tblBooks.AuthorFirstName, R.SKU
FROM Items 
INNER JOIN 
   (SELECT TOP 10 Recommended.ProductCode, Recommended.SKU FROM Recommended 
   INNER JOIN Stock ON Recommended.ProductCode = Stock.ProductCode AND 
   Stock.StatusCode = 1 WHERE (Recommended.Type = 'TOPICAL') 
   ORDER BY CHECKSUM(NEWID())) 
AS Rec ON Items.ProductCode = Rec.ProductCode;

Выше приведен правильный синтаксис в MySQL, ваш пробег может отличаться ...

0 голосов
/ 15 мая 2009

При таких обстоятельствах я обычно использовал бы внутреннее соединение, чтобы получить фильтрацию строк из необходимого мне предложения where и дополнительных столбцов. Что-то вроде ниже; если это то, что вы сделали, что привело к снижению производительности, возможно, вам придется перевернуть запрос; перейти от рекомендуемого и присоединиться к пунктам; поскольку это, вероятно, приведет к дополнительной фильтрации данных перед объединением.

SELECT Items.Name, tblBooks.AuthorLastName, tblBooks.AuthorFirstName
FROM Items 
Inner Join
(
SELECT TOP 10 Recommended.ProductCode, SKUID
FROM 
Recommended 
INNER JOIN Stock ON Recomended.ProductCode = Stock.ProductCode
AND Stock.StatusCode = 1
WHERE (Recommended.Type = 'TOPICAL')
) reccomended
on items.productcode - reccomended.ProductCode


ORDER BY CHECKSUM(NEWID()
0 голосов
/ 15 мая 2009

Вы можете вернуть только одно значение с помощью подвыбора, поэтому вы должны получить поля из таблицы Рекомендованных с помощью объединения - я полагаю, это то, что вы уже имеете:

SELECT Items.Name, tblBooks.AuthorLastName, tblBooks.AuthorFirstName, Recommended.SKU
FROM Items 
INNER JOIN Recommended ON Recommended.ProductCode = Items.ProductCode
WHERE Items.ProductCode IN (
SELECT TOP 10 Recommended.ProductCode
FROM 
Recommended 
INNER JOIN Stock ON Recomended.ProductCode = Stock.ProductCode
AND Stock.StatusCode = 1
WHERE (Recommended.Type = 'TOPICAL') ORDER BY CHECKSUM(NEWID()));

Скорее всего, соединение в реальности тоже внешнее. Это действительно не должно иметь никаких проблем с производительностью, если у вас есть и Предметы, и Рекомендованные таблицы, проиндексированные в ProductCode.

...