自加入 SQL 具有聚合的服务器
Self Join SQL Server with aggregates
我有一个查询,returns 所有会话都在当天开始,然后给我当前活动会话的计数和自上次登录以来的时间。 (这让我知道是否有内核出现任何导致用户无法登录的问题)
SELECT [server]
, appserver
, count(*) as open_sessions
, max(start_time) Latest_New_Login
, datediff(minute, max(start_time) , GETDATE() ) elapsed_mins_since_last_login
FROM [session_logs]
where DATEDIFF(day, START_TIME, GETDATE()) <= 0
and end_time is null
group by server, appserver
order by 1,2
数据返回
+---------+-----------+---------------+-------------------------+-------------------------------+
| server | appserver | open_sessions | Latest_New_Login | Elapsed_mins_since_last_login |
+---------+-----------+---------------+-------------------------+-------------------------------+
| SERVER1 | PK1 | 13 | 2018-01-26 16:24:47.087 | 1 |
| SERVER1 | PK2 | 12 | 2018-01-26 16:19:00.157 | 6 |
| SERVER2 | PK1 | 8 | 2018-01-26 16:25:41.297 | 0 |
| SERVER2 | PK2 | 6 | 2018-01-26 16:07:31.027 | 18 |
| SERVER3 | PK1 | 7 | 2018-01-26 16:18:56.597 | 7 |
| SERVER3 | PK2 | 5 | 2018-01-26 16:19:06.550 | 6 |
+---------+-----------+---------------+-------------------------+-------------------------------+
一切都很好,
但是我需要一种解决方法来确保显示所有服务器和应用程序服务器。今天我们遇到了一个问题,服务器 3 PK1 上没有显示任何活动登录,这从我的结果中删除了它的条目 table。
有没有办法让我始终显示以下数据集并让我的聚合函数与它们相符?一个自连接查询,但我无法让它工作。
select distinct [server], appserver
FROM [session_logs]
returns 值
Server 1 PK1
Server 1 PK2
Server 2 PK1
Server 2 PK2
Server 3 PK1
Server 3 PK2
做一个LEFT JOIN
:
SELECT
serv.[server],
serv.appserver,
t.open_sessions,
t.Latest_New_Login,
t.elapsed_mins_since_last_login
FROM (
SELECT DISTINCT [server], appserver FROM [session_logs]
) serv
LEFT JOIN (
SELECT [server]
, appserver
, COUNT(*) AS open_sessions
, MAX(start_time) AS Latest_New_Login
, DATEDIFF(MINUTE, MAX(start_time), GETDATE()) AS elapsed_mins_since_last_login
FROM [session_logs]
WHERE
DATEDIFF(day, START_TIME, GETDATE()) <= 0
AND end_time is null
GROUP BY [server], appserver
) t
ON t.[server] = serv.[server]
AND t.appserver = serv.appserver
ORDER BY
serv.[server], serv.appserver
如果您有一个 table 来保存您的服务器列表,请使用它来代替:
SELECT DISTINCT [server], appserver FROM [session_logs]
不使用的另一种选择JOIN
select
[server]
, appserver
, count(start_time) as open_sessions
, max(start_time) Latest_New_Login
, datediff(minute, max(start_time) , GETDATE() ) elapsed_mins_since_last_login
from (
SELECT [server]
, appserver
, start_time
FROM
[session_logs]
where
DATEDIFF(day, START_TIME, GETDATE()) <= 0
and end_time is null
union all select distinct [server], appserver, null FROM [session_logs]
) t
group by server, appserver
构建一个包含所有唯一服务器的通用 Table 表达式,并在其上进行 LEFT JOIN:
;with cte([server], appserver)
as (
select distinct [server], appserver
from [session_logs]
-- let's limit with records from last 30 days in case [session_logs] is a massive table
-- I assume all servers you care about had some activity in that time
where DATEDIFF(day, START_TIME, GETDATE()) <= 30
)
SELECT cte.[server]
, cte.appserver
, count(start_time) as open_sessions
, max(start_time) Latest_New_Login
, datediff(minute, max(start_time), GETDATE()) Elapsed_mins_since_last_login
FROM cte
left join [session_logs] as sl on cte.[server] = sl.[server] and cte.appserver = sl.appserver
where DATEDIFF(day, START_TIME, GETDATE()) <= 0
and end_time is null
group by cte.[server], cte.appserver
order by cte.[server], cte.appserver
我有一个查询,returns 所有会话都在当天开始,然后给我当前活动会话的计数和自上次登录以来的时间。 (这让我知道是否有内核出现任何导致用户无法登录的问题)
SELECT [server]
, appserver
, count(*) as open_sessions
, max(start_time) Latest_New_Login
, datediff(minute, max(start_time) , GETDATE() ) elapsed_mins_since_last_login
FROM [session_logs]
where DATEDIFF(day, START_TIME, GETDATE()) <= 0
and end_time is null
group by server, appserver
order by 1,2
数据返回
+---------+-----------+---------------+-------------------------+-------------------------------+
| server | appserver | open_sessions | Latest_New_Login | Elapsed_mins_since_last_login |
+---------+-----------+---------------+-------------------------+-------------------------------+
| SERVER1 | PK1 | 13 | 2018-01-26 16:24:47.087 | 1 |
| SERVER1 | PK2 | 12 | 2018-01-26 16:19:00.157 | 6 |
| SERVER2 | PK1 | 8 | 2018-01-26 16:25:41.297 | 0 |
| SERVER2 | PK2 | 6 | 2018-01-26 16:07:31.027 | 18 |
| SERVER3 | PK1 | 7 | 2018-01-26 16:18:56.597 | 7 |
| SERVER3 | PK2 | 5 | 2018-01-26 16:19:06.550 | 6 |
+---------+-----------+---------------+-------------------------+-------------------------------+
一切都很好, 但是我需要一种解决方法来确保显示所有服务器和应用程序服务器。今天我们遇到了一个问题,服务器 3 PK1 上没有显示任何活动登录,这从我的结果中删除了它的条目 table。
有没有办法让我始终显示以下数据集并让我的聚合函数与它们相符?一个自连接查询,但我无法让它工作。
select distinct [server], appserver
FROM [session_logs]
returns 值
Server 1 PK1
Server 1 PK2
Server 2 PK1
Server 2 PK2
Server 3 PK1
Server 3 PK2
做一个LEFT JOIN
:
SELECT
serv.[server],
serv.appserver,
t.open_sessions,
t.Latest_New_Login,
t.elapsed_mins_since_last_login
FROM (
SELECT DISTINCT [server], appserver FROM [session_logs]
) serv
LEFT JOIN (
SELECT [server]
, appserver
, COUNT(*) AS open_sessions
, MAX(start_time) AS Latest_New_Login
, DATEDIFF(MINUTE, MAX(start_time), GETDATE()) AS elapsed_mins_since_last_login
FROM [session_logs]
WHERE
DATEDIFF(day, START_TIME, GETDATE()) <= 0
AND end_time is null
GROUP BY [server], appserver
) t
ON t.[server] = serv.[server]
AND t.appserver = serv.appserver
ORDER BY
serv.[server], serv.appserver
如果您有一个 table 来保存您的服务器列表,请使用它来代替:
SELECT DISTINCT [server], appserver FROM [session_logs]
不使用的另一种选择JOIN
select
[server]
, appserver
, count(start_time) as open_sessions
, max(start_time) Latest_New_Login
, datediff(minute, max(start_time) , GETDATE() ) elapsed_mins_since_last_login
from (
SELECT [server]
, appserver
, start_time
FROM
[session_logs]
where
DATEDIFF(day, START_TIME, GETDATE()) <= 0
and end_time is null
union all select distinct [server], appserver, null FROM [session_logs]
) t
group by server, appserver
构建一个包含所有唯一服务器的通用 Table 表达式,并在其上进行 LEFT JOIN:
;with cte([server], appserver)
as (
select distinct [server], appserver
from [session_logs]
-- let's limit with records from last 30 days in case [session_logs] is a massive table
-- I assume all servers you care about had some activity in that time
where DATEDIFF(day, START_TIME, GETDATE()) <= 30
)
SELECT cte.[server]
, cte.appserver
, count(start_time) as open_sessions
, max(start_time) Latest_New_Login
, datediff(minute, max(start_time), GETDATE()) Elapsed_mins_since_last_login
FROM cte
left join [session_logs] as sl on cte.[server] = sl.[server] and cte.appserver = sl.appserver
where DATEDIFF(day, START_TIME, GETDATE()) <= 0
and end_time is null
group by cte.[server], cte.appserver
order by cte.[server], cte.appserver