我有两个表,一个表用于某种设备,另一个表用于其位置(使用此表记录位置历史记录)。表的架构为:
tbl_Devices:
tbl_DeviceLocation
我需要的是DeviceSrNumber
,最后一个Location
,最后一个位置集AddDateTime
我现在在做什么:
SELECT
DeviceSrNumber,
(
SELECT TOP (1) Location
FROM tbl_DeviceLocation
WHERE (DeviceSrNumber = d.DeviceSrNumber)
ORDER BY AddDateTime DESC
) AS 'Location',
(
SELECT TOP (1) AddDateTime
FROM tbl_DeviceLocation
WHERE (DeviceSrNumber = d.DeviceSrNumber)
ORDER BY AddDateTime DESC
) AS 'AddDateTime '
FROM
tbl_Devices AS d
但是我需要以一种更简洁的方式进行连接,因为据我所知,子查询效率不高,因此不建议在大型数据库中使用。
注意:这只是大型项目的一小部分,它将处理数百万条记录。
答案 0 :(得分:1)
您可以从这里开始:
SELECT *
FROM (
SELECT
d.DeviceSrNumber
, dl.Location LastLocation
, dl.AddDateTime LastLocationSetDateTime
, ROW_NUMBER() OVER(PARTITION BY d.DeviceSrNumber ORDER BY AddDateTime DESC) RN
FROM
tbl_Devices d
JOIN tbl_DeviceLocation dl ON dl.DeviceSrNumber = d.DeviceSrNumber
) D
WHERE
RN = 1
更新
SELECT
d.DeviceSrNumber
, MAX(dl.Location) LastLocation
, MAX(dl.AddDateTime) LastLocationSetDateTime
FROM
tbl_Devices d
JOIN tbl_DeviceLocation dl ON dl.DeviceSrNumber = d.DeviceSrNumber
GROUP BY d.DeviceSrNumber
ORDER BY AddDateTime DESC
答案 1 :(得分:1)
您的查询将以这种方式更加高效:
SELECT D.DeviceSrNumber,
L.Location,
L.AddDateTime
FROM tbl_Devices D
OUTER APPLY
(SELECT TOP (1) DL.Location, DL.AddDateTime
FROM tbl_DeviceLocation DL
WHERE D.DeviceSrNumber = DL.DeviceSrNumber
ORDER BY DL.AddDateTime DESC
) L;
答案 2 :(得分:-1)
尝试此操作,它将使用最新的AddDateTime选择一个数据
SELECT top(1) D.DeviceSrNumber, L.Location,L.AddDateTime
FROM tbl_Devices AS D
JOIN tbl_DeviceLoation AS L ON D.DeviceSrNumber = L.DeviceSrNumber
WHERE D.DeviceSrNumber = L.DeviceSrNumber order by L.AddDateTime desc
更新
我尝试过此操作,它根据最新记录选择了不同的记录。希望能解决
WITH CTE AS
(
SELECT D.DeviceSrNumber, L.Location,L.AddDateTime , RN= ROW_NUMBER() OVER (PARTITION BY D.DeviceSrNumber ORDER BY D.DeviceSrNumber)
FROM tbl_Devices AS D LEFT JOIN tbl_DeviceLoation AS L ON D.DeviceSrNumber = L.DeviceSrNumber
WHERE D.DeviceSrNumber = L.DeviceSrNumber group by D.DeviceSrNumber, L.Location,L.AddDateTime )
SELECT * FROM CTE where RN=1 order by CTE.AddDateTime desc