如何仅从左侧 table 获取一条记录,而从右侧 table 获取每条记录

How to get only one record from left table against each record from right table

我有两个 table,一个用于某种设备,另一个用于它们的位置(使用这个 table 来记录位置历史记录)。表的架构是:

  1. tbl_Devices:

    • DeviceSrNumber(bigint,不为空,pk)
    • 其他一些栏目
  2. tbl_DeviceLocation

    • SrNumber (bigint, not null, pk, identity)
    • DeviceSrNumber(bigint,不为空)
    • 位置(varchar(300),不为空)
    • AddDateTime(日期时间,不为空)

我需要的是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

但我需要以更简洁的方式使用连接来完成,因为据我所知,子查询效率不高,不建议在大型数据库中使用。

注意:它是一个大型项目的一小部分,它将处理数百万条记录。

你可以从这个开始:

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

这样您的查询会更有效率:

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;

试试这个,它会 select 使用最新的 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

更新

我试过了,它根据最新记录 select 不同的记录。希望这能解决问题

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