如何从子查询(在 SQLServer 中)中为主查询中的每条记录选择应该有一条记录(选择 top 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个子查询)的正确语法是什么?非常感谢。

485677 次浏览
select t1.*, sq.*
from table1 t1,
(select a,b,c from table2 ...) sq
where ...

你必须加入:

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.idB上的 PRIMARY KEY

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精确地选择一条记录。

以下是如何从子查询中选择多个列的一般方法:

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 的最大值(而不是 Foo 的最大值和 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。

我觉得这就是你想要的。

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'
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'