我有一个查询,从表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中最早的记录?
答案 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;