我需要在MSSQL查詢返回以下結果返回不同的上次登錄日期:根據從最近的日期從下表
客戶端ID,用戶名,EVENTDATE
明顯的每個客戶端ID如下表所示:
例如:鑑於上面的表格,返回:
450SB 2013-03-01 16:40:29 nevadan
LASB 2013-03 001 16:37:27 siteuser
等
正想着,創造了一個光標:從表 DISTINCT客戶端Id和通過的maxDate的各只返回進入循環,但沒想到它 是非常有效的。
我需要在MSSQL查詢返回以下結果返回不同的上次登錄日期:根據從最近的日期從下表
客戶端ID,用戶名,EVENTDATE
明顯的每個客戶端ID如下表所示:
例如:鑑於上面的表格,返回:
450SB 2013-03-01 16:40:29 nevadan
LASB 2013-03 001 16:37:27 siteuser
等
正想着,創造了一個光標:從表 DISTINCT客戶端Id和通過的maxDate的各只返回進入循環,但沒想到它 是非常有效的。
可以使用CTE抓住每個客戶端的最新訪問日期,然後再加入回到了CTE來獲取每個客戶端的每個最新訪問日期的用戶名。如果您的表具有主鍵,則JOIN在性能,可讀性和優雅方面會更好。
;WITH latestClientAccess (ClientId, LatestEventDate) AS (
SELECT ClientId, MAX(EventDate)
FROM MyTable
GROUP BY ClientId
)
SELECT t.ClientId, t.UserName, lca.LatestEventDate [EventDate]
FROM MyTable t
INNER JOIN latestClientAccess lca
ON t.ClientId=lca.ClientId
AND t.EventDate=lca.LatestEventDate
通過運行下面的腳本可以執行上述概念和腳本的快速本地測試。這樣,任何查看此響應的人都可以測試,而無需創建任何模式。
declare @temp table(ClientId int, EventDate datetime, UserName varchar(20))
insert into @temp
select 1, '2015-11-06 00:00:00', 'user1'
insert into @temp
select 2, '2015-11-06 00:01:00', 'user1'
insert into @temp
select 1, '2015-11-06 00:01:00', 'user2'
insert into @temp
select 1, '2015-11-06 00:03:00', 'user1'
;WITH latestClientAccess (ClientId, LatestEventDate) AS (
SELECT ClientId, MAX(EventDate)
FROM @temp
GROUP BY ClientId
)
SELECT t.ClientId, t.UserName, lca.LatestEventDate [EventDate]
FROM @temp t
INNER JOIN latestClientAccess lca
ON t.ClientId=lca.ClientId
AND t.EventDate=lca.LatestEventDate
編輯
考慮你有一個主鍵和一個第二表的客戶名稱,考慮下面的腳本:
;WITH latestClientAccess (ClientId, HistoryId) AS (
SELECT ClientId, MAX(HistoryId)
FROM MyTable
GROUP BY ClientId
)
SELECT ct.ClientName, t.UserName, t.EventDate
FROM MyTable t
INNER JOIN latestClientAccess lca
ON t.HistoryId=lca.HistoryId
INNER JOIN MyClientTable ct
ON t.ClientId=ct.ClientId
對於最新事件概念的快速測試(無客戶名稱):
declare @temp table(HistoryId int, ClientId int, EventDate datetime, UserName varchar(20))
insert into @temp
select 1, 1, '2015-11-06 00:00:00', 'user1'
insert into @temp
select 2, 2, '2015-11-06 00:01:00', 'user1'
insert into @temp
select 3, 1, '2015-11-06 00:01:00', 'user2'
insert into @temp
select 4, 1, '2015-11-06 00:03:00', 'user1'
;WITH latestClientAccess (ClientId, HistoryId) AS (
SELECT ClientId, MAX(HistoryId)
FROM @temp
GROUP BY ClientId
)
SELECT t.ClientId, t.UserName, t.EventDate
FROM @temp t
INNER JOIN latestClientAccess lca
ON t.HistoryId=lca.HistoryId
我沒有在我的計算機上安裝MSSQL,因此我無法爲您測試此選項,但是我認爲您可以將「ORDERBY ASC eventdate」篩選器添加到您的SQL中,然後僅選擇第一行來實現您的目標。
因此,這將是像
SELECT DISTINCT客戶端Id FROM表 ORDER BY EVENTDATE
至於這是否是更有效的或不...我想你預訂購一定要看查詢執行計劃來查看MSSQL做什麼操作來執行查詢,性能可能不如您以前的那樣好,因爲這個SQL正在做一些額外的事情,那就是排序。
通過這種方法至少你不必自己認爲有效的排序算法,並將其保存的密碼算法和兩行的你時間思考:P
Msg 145,Level 15,State 1,Lin e 1 如果指定了SELECT DISTINCT,則ORDER BY項目必須出現在選擇列表中。 –
Ooops,我沒有太多的MSSQL經驗,但你可以嘗試使用GROUP BY而不是DISTINCT?所以像這樣的東西; 從表組中選擇ClientID,UserName,EventDate按ClientId排序由eventdate asc –
你所描述的是一個有點複雜人們會認爲,主要是因爲除了ClientID和EventDate之外,您還需要UserName。
這應該可以工作,雖然我沒有在本地構建您的模式來測試,所以讓我知道如果你有任何錯誤。
SELECT
t1.*
FROM
SomeTable t1
INNER JOIN
(
SELECT
ClientId
MaxEventDate = MAX(EventDate)
FROM
SomeTable
GROUP BY
ClientId
) t2
ON
t1.ClientID = t2.ClientID
AND t1.EventDate = t2.EventDate
...注意:如果你擺脫用戶名的,它只是:
SELECT
ClientId
MaxEventDate = MAX(EventDate)
FROM
SomeTable
GROUP BY
ClientId
它確實有一個主要的:歷史ID - 謝謝。 –
如果HistoryID是一個不斷增加的標識字段,您可以使用MAX(HistoryID)而不是MAX(EventDate)。這可能會加快聯接的速度。 –
謝謝你,先生。如果我想在查詢中返回一個更清晰的clientId名稱,它位於tableB中,作爲tableb.sccClientID = table.clientId上的sccCompanyName字段。我將如何修改您的查詢? –