在子查询中选择多个列

时间:2014-09-17 12:02:04

标签: sql ms-access

我有一个查询,从表B中选择最旧的记录,其中包含表A中每行的多行,并将其连接到表A:

SELECT A.Surname, A.Fornames, A.DOB, 
(SELECT TOP 1 B.RegNumber
   FROM B
   WHERE B.ID=A.ID 
   ORDER BY B.Date ASC) AS RegNumber
FROM A
ORDER BY A.Surname;

这很好用,但是我也想从表B中拉出另一列。所以我会:

A.Surname, A.Fornames, A.DOB, B.RegNumber, B.RegDate

我怎样才能这样做,同时仍然只能获得表B中最早的记录?

3 个答案:

答案 0 :(得分:3)

您可以重复子查询:

SELECT A.Surname, A.Fornames, A.DOB, 
       (SELECT TOP 1 B.RegNumber
        FROM B
        WHERE B.ID=A.ID 
        ORDER BY B.Date ASC
       ) AS RegNumber,
       (SELECT min(b.Date)
        FROM B
        WHERE B.ID=A.ID 
       ) AS RegDate
FROM A
ORDER BY A.Surname;

答案 1 :(得分:2)

您有两个选择,第一个是使用连接重构您的查询:

原则是,您需要获得按B分组的ID中每条记录的第一个日期:

SELECT  ID, MIN(Date) AS [FirstDate]
FROM    B
GROUP BY ID;

然后,您可以将其加回到B,以过滤结果,即:

SELECT  B.*
FROM    B
        INNER JOIN
        (   SELECT  ID, MIN(Date) AS [FirstDate]
            FROM    B
            GROUP BY ID
        ) AS B2
            ON B2.ID = B.ID
            AND B2.FirstDate = B.Date;;

然后,您可以将其加入表A并选择所需的所有字段:

SELECT  A.Surname, A.Fornames, A.DOB, B.RegNumber, B.RegDate
FROM    (A
        INNER JOIN B
            ON B.ID = A.ID)
        INNER JOIN
        (   SELECT  ID, MIN(Date) AS [FirstDate]
            FROM    B
            GROUP BY ID
        ) AS B2
            ON B2.ID = B.ID
            AND B2.FirstDate = B.Date
ORDER BY A.Surname;

使用JOIN的替代方法是:

SELECT  A.Surname, A.Fornames, A.DOB, B.RegNumber, B.RegDate
FROM    (A
        INNER JOIN B
            ON A.ID = B.ID)
        LEFT JOIN B AS B2
            ON B2.ID = B.ID
            AND B2.Date < B.Date
WHERE   B2.ID IS NULL
ORDER BY A.Surname;

此方法的工作原理是加入B两次,第二次(B2)获取比第一次加入(B)中的记录更早的所有记录,然后通过声明B2.ID为空,您实际上是说您想要B中的所有记录,其中不存在具有相同ID和较早日期的记录。

第二种方法是重复你的相关子查询:

SELECT A.Surname, A.Fornames, A.DOB, 
    (SELECT TOP 1 B.RegNumber
        FROM B
        WHERE B.ID=A.ID 
        ORDER BY B.Date ASC) AS RegNumber
    (SELECT TOP 1 B.RegDate
        FROM B
        WHERE B.ID=A.ID 
        ORDER BY B.Date ASC) AS RegDate
FROM A
ORDER BY A.Surname;

如果您只是从表中访问两列,则几乎没有将两种方法分开,两者都要求B被读取两次,但是使用JOIN往往会给优化器提供更好的机会,所以我会转向这种方法。另一个优点是它允许您访问B中的所有字段,因此如果您需要第三列,则不必添加第三个相关子查询。

答案 2 :(得分:-2)

试试这个......

SELECT A.Surname, A.Fornames, A.DOB, B.RegNumber, B.RegDate
FROM A
JOIN (
    Select top 1 RegNumber, RegDate
    From B
    WHERE B.ID = A.ID
    Order By B.Date ASC
) B on A.ID = B.ID
ORDER BY A.Surname;

这就是我将一些代码放在一起所得到的。上面的例子返回一个&#34; id&#34;无法绑定错误。不确定这是否是您正在寻找的,但我尝试了一些示例代码。

SELECT A.Surname, A.Fornames, A.DOB, MIN(B.RegNumber) As RegNumber, MIN(B.RegDate) as RegDate
FROM A
JOIN (
    Select ID, RegNumber, RegDate
    From B
) B on A.ID = B.ID
Group By A.Surname, A.Fornames, A.DOB
ORDER BY A.Surname;