我有以下数据。
Base table
Id DateTime
201 2015-05-03 08:01
301 2015-05-03 08:20
401 2015-05-03 08:40
Extract Table
Id DateTime Location
201 2015-05-03 07:50 City A
201 2015-05-03 08:01 City B
201 2015-05-03 08:50 City C
301 2015-05-03 07:15 City E
301 2015-05-03 08:01 City F
301 2015-05-03 08:20 City G
401 2015-05-03 08:40 City X
401 2015-05-03 08:55 City Y
Desired Result:
Location Id DateTime
City A 201 2015-05-03 07:50
City E 301 2015-05-03 07:15
City X 401 2015-05-03 08:40
要清除图片,我正在尝试为他们签到的每个客户获取第一个位置。由于我将过滤一些我需要的位置
WHERE Location in ('City A','City B','City C','City E','City F','City G','City X','City Y')
感谢。
答案 0 :(得分:0)
也许这就是你想要的?
select b.id,
(CASE WHEN b.ADateTime = e.RDateTime THEN e.Location
ELSE (SELECT TOP 1 e.Location
FROM Extract e2
WHERE e2.id = e.id
ORDER BY RdateTime ASC
)
END) AS [Test],
a.Location
from Base b inner join
Extract e
on b.id = e.id
where b.id = 301;
这会获得与最小匹配id
相关联的位置。肯定有其他方法来表达这种逻辑,假设这是你真正想要的。
答案 1 :(得分:0)
我仍然认为LEFT JOIN是要走的路:
SELECT extract.id, extract.location
FROM [base]
INNER JOIN [extract] ON [base].id = [extract].id
LEFT JOIN extract [earlierExtract] ON [extract].id = [earlierExtract].id
AND [earlierExtract].DATETIME < [extract].DATETIME
AND [earlierExtract].Location IN (
'City A'
,'City B'
,'City C'
,'City E'
,'City F'
,'City G'
,'City X'
,'City Y'
)
WHERE extract.Location IN (
'City A'
,'City B'
,'City C'
,'City E'
,'City F'
,'City G'
,'City X'
,'City Y'
)
AND earlierextract.id IS NULL
答案 2 :(得分:0)
获得所需内容的最简单方法是使用窗口聚合函数,ROW_NUMBER:
select *
from
(
SELECT ...,
ROW_NUMBER() -- assign a sequence, oldest row gets 1
OVER (PARTITION BY e.id
ORDER BY e.[DateTime]) as rn
FROM [base] as b
JOIN [extract] as e
ON b.id = e.id
WHERE Location in ('City A','City B','City C','City E','City F','City G','City X','City Y')
AND ... -- any additional filter you need
) as dt
WHERE rn = 1 -- first join all rows, then return only the oldest.
答案 3 :(得分:0)
另一种解决方案是使用EXISTS,仅返回最早的记录。
--Sample data population...
DECLARE @BaseTable TABLE (ID INT, DateTime SMALLDATETIME)
DECLARE @ExtractTable TABLE (ID INT, DateTime SMALLDATETIME, Location VARCHAR(25))
INSERT INTO @BaseTable (ID, DateTime) SELECT 201, '2015-05-03 08:01'
INSERT INTO @BaseTable (ID, DateTime) SELECT 301, '2015-05-03 08:20'
INSERT INTO @BaseTable (ID, DateTime) SELECT 401, '2015-05-03 08:40'
INSERT INTO @ExtractTable (ID, DateTime, Location) SELECT 201, '2015-05-03 07:50', 'City A'
INSERT INTO @ExtractTable (ID, DateTime, Location) SELECT 201, '2015-05-03 08:01', 'City B'
INSERT INTO @ExtractTable (ID, DateTime, Location) SELECT 201, '2015-05-03 08:50', 'City C'
INSERT INTO @ExtractTable (ID, DateTime, Location) SELECT 301, '2015-05-03 07:15', 'City E'
INSERT INTO @ExtractTable (ID, DateTime, Location) SELECT 301, '2015-05-03 08:01', 'City F'
INSERT INTO @ExtractTable (ID, DateTime, Location) SELECT 401, '2015-05-03 08:40', 'City X'
INSERT INTO @ExtractTable (ID, DateTime, Location) SELECT 401, '2015-05-03 08:55', 'City Y'
--Example of lookup, using EXISTS to bring back the earliest check-in location of the customer...
SELECT
ExtractTable.Location
,BaseTable.ID
,ExtractTable.DateTime
FROM @BaseTable BaseTable
INNER JOIN @ExtractTable ExtractTable ON
EXISTS
(
SELECT 1
FROM @ExtractTable Ext
WHERE Ext.ID=BaseTable.ID
GROUP BY Ext.ID
HAVING MIN(Ext.DateTime)=ExtractTable.DateTime
)
WHERE ExtractTable.Location IN
(
'City A'
,'City B'
,'City C'
,'City E'
,'City F'
,'City G'
,'City X'
,'City Y'
)
我认为你会发现这比现有解决方案更易于管理。