Как я могу выбрать несколько столбцов из подзапроса (в SQL Server), который должен иметь одну запись (выберите верхнюю часть 1) для каждой записи в основном запросе?
Знаю, что я могу выбрать столбец из подзапроса с помощью этого синтаксиса:
SELECT A.SalesOrderID, A.OrderDate,
(
SELECT TOP 1 B.Foo
FROM B
WHERE A.SalesOrderID = B.SalesOrderID
) AS FooFromB
FROM A
WHERE A.Date BETWEEN '2000-1-4' AND '2010-1-4'
Но каков правильный синтаксис для использования нескольких столбцов в подзапросе (в моем случае выбрать первый подзапрос 1)? Большое вам спасибо.
Ответы
Ответ 1
Здесь вообще как выбрать несколько столбцов из подзапроса:
SELECT
A.SalesOrderID,
A.OrderDate,
SQ.Max_Foo,
SQ.Max_Foo2
FROM
A
LEFT OUTER JOIN
(
SELECT
B.SalesOrderID,
MAX(B.Foo) AS Max_Foo,
MAX(B.Foo2) AS Max_Foo2
FROM
B
GROUP BY
B.SalesOrderID
) AS SQ ON SQ.SalesOrderID = A.SalesOrderID
Если то, что вы в конечном итоге пытаетесь сделать, это получить значения из строки с наивысшим значением для Foo (а не max Foo и max Foo2 - это НЕ то же самое), тогда обычно будет следующее: работать лучше, чем подзапрос:
SELECT
A.SalesOrderID,
A.OrderDate,
B1.Foo,
B1.Foo2
FROM
A
LEFT OUTER JOIN B AS B1 ON
B1.SalesOrderID = A.SalesOrderID
LEFT OUTER JOIN B AS B2 ON
B2.SalesOrderID = A.SalesOrderID AND
B2.Foo > B1.Foo
WHERE
B2.SalesOrderID IS NULL
Вы в основном говорите, дайте мне строку из B, где я не могу найти другую строку из B с тем же SalesOrderID и большим Foo.
Ответ 2
SELECT a.salesorderid, a.orderdate, s.orderdate, s.salesorderid
FROM A a
OUTER APPLY (SELECT top(1) *
FROM B b WHERE a.salesorderid = b.salesorderid) as s
WHERE A.Date BETWEEN '2000-1-4' AND '2010-1-4'
Ответ 3
Вам нужно сделать соединение:
SELECT A.SalesOrderID, B.Foo
FROM A
JOIN B bo ON bo.id = (
SELECT TOP 1 id
FROM B bi
WHERE bi.SalesOrderID = a.SalesOrderID
ORDER BY bi.whatever
)
WHERE A.Date BETWEEN '2000-1-4' AND '2010-1-4'
считая, что b.id
является PRIMARY KEY
на B
В MS SQL 2005
и выше вы можете использовать этот синтаксис:
SELECT SalesOrderID, Foo
FROM (
SELECT A.SalesOrderId, B.Foo,
ROW_NUMBER() OVER (PARTITION BY B.SalesOrderId ORDER BY B.whatever) AS rn
FROM A
JOIN B ON B.SalesOrderID = A.SalesOrderID
WHERE A.Date BETWEEN '2000-1-4' AND '2010-1-4'
) i
WHERE rn
Это выберет ровно одну запись из B
для каждого SalesOrderId
.
Ответ 4
Я думаю, это то, что вы хотите.
SELECT
A.SalesOrderID,
A.OrderDate,
FooFromB.*
FROM A,
(SELECT TOP 1 B.Foo
FROM B
WHERE A.SalesOrderID = B.SalesOrderID
) AS FooFromB
WHERE A.Date BETWEEN '2000-1-4' AND '2010-1-4'
Ответ 5
select t1.*, sq.*
from table1 t1,
(select a,b,c from table2 ...) sq
where ...