如何从子查询中select多个列(在SQL Server中),对于主查询中的每个logging应该有一个logging(selecttop 1)?

我知道我可以使用以下语法从子查询中select一列:

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' 

但是,从子查询中使用多个列的正确语法是什么(在我的情况下是select top 1子查询)? 非常感谢你。

一般来说,如何从子查询中select多个列:

 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的行,我不能find任何其他行B与相同的SalesOrderID和更大的Foo。

你必须join:

 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 

这将为每个SalesOrderIdB精确select一条logging。

 SELECT T1.PrimaryKey, T1.SomeColumn, MySubQuery.Col1, MySubQuery.Col2, MySubQuery.Col3 From Table1 T1 LEFT JOIN (SELECT TOP 1 Col1, Col2, Col3, Fkey FROM Table 2 ORDER BY Col1 DESC) AS MySubQuery ON T1.PrimaryKey = MySubQuery.Fkey 
 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' 

我想这就是你想要的。

 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'