在下面的SELECT语句中,我希望从一个表中获得COUNT个连接,在该表中,每个唯一transactionID的连接定义为1个连接。
因此,在我的COUNT个帐户中,我要检查以确保尚未建立连接(即,相同的transactionID,但主键ID较低)。
我尝试使用COUNT(DISTINCT pc.TransactionID),但问题是在每个分组(ThisDate,SiteName,UserName,Command)中都可能出现相同的transactionID,因此它多次计数某些连接。
然后我尝试加入同一张表,并使用SUM代替COUNT,这似乎可行,但是由于拉入了额外的记录,因此增加了BytesTransferred值。
想法是解决此问题的最佳方法吗?
ProtocolCommands表
ProtocolCommandID, int, not null, primary key
Time_Stamp Datetime
SiteName nvarchar(50) null
UserName nvarchar(50) null
Command nvarchar(50) null
BytesTransferred numeric(18,0) null
TransactionID int not null
选择语句
SELECT
CONVERT(date,pc.Time_stamp) As ThisDate,
pc.SiteName,
pc.UserName,
pc.Command,
SUM(CASE WHEN p.TransactionID IS NULL THEN 1 ELSE 0 END) As Connections,
-- COUNT(DISTINCT pc.TransactionID) AS Connections,
SUM(pc.BytesTransferred) AS DataTransferred
FROM ProtocolCommands pc
LEFT OUTER JOIN ProtocolCommands p ON p.TransactionID = pc.TransactionID AND p.ProtocolCommandID < pc.ProtocolCommandID
WHERE pc.Time_Stamp >= '01/01/2019'
GROUP BY CONVERT(date,pc.Time_stamp),pc.SiteName, pc.UserName, pc.Command
举个例子,这里有一些记录:
Time_stamp SiteName UserName Command BytesTransferred TransactionID
2019-04-20 MySite Joe connect 2000 12345
2019-04-20 MySite Joe send 20000 12345
2019-04-21 MySite Joe retrieve 25952 12345
2019-04-21 MySite Joe send 30000 12345
使用COUNT(DISTINCT pc.TransactionID)执行SELECT并删除内部联接时,结果如下(注意最后两行的DataTransferred错误):
ThisDate SiteName UserName Command Connections DataTransferred
2019-04-20 MySite Joe connect 1 2000
2019-04-20 MySite Joe send 0 20000
2019-04-21 MySite Joe retrieve 0 51904
2019-04-21 MySite Joe send 0 90000
使用SUM执行SELECT并添加内部联接时,结果是这样的(注意错误的Connections-总共应该只有1个):
ThisDate SiteName UserName Command Connections DataTransferred
2019-04-20 MySite Joe connect 1 2000
2019-04-20 MySite Joe send 1 20000
2019-04-21 MySite Joe retrieve 1 25952
2019-04-21 MySite Joe send 1 30000
预期结果:
ThisDate SiteName UserName Command Connections DataTransferred
2019-04-20 MySite Joe connect 1 2000
2019-04-20 MySite Joe send 0 20000
2019-04-21 MySite Joe retrieve 0 25952
2019-04-21 MySite Joe send 0 30000
答案 0 :(得分:1)
不确定我是否理解正确,但是您似乎想检测最早出现的连接。您可以使用以下查询来做到这一点:
SELECT ROW_NUMBER() OVER (PARTITION BY TransactionId ORDER BY ProtocolCommandID ASC) as RowNum
, ProtocolCommandId
FROM ProtocolCommands
对于第一次出现连接的记录,该行的RowNum = 1。
将其加入到主表中,您可以获得正确的连接数
SELECT
CONVERT(date,pc.Time_stamp) As ThisDate,
pc.SiteName,
pc.UserName,
pc.Command,
CASE WHEN first_conn.RowNum = 1 THEN SUM(first_conn.RowNum) ELSE 0 END AS Connection,
SUM(pc.BytesTransferred) AS DataTransferred
FROM ProtocolCommands pc
LEFT OUTER JOIN
(SELECT ROW_NUMBER() OVER (PARTITION BY TransactionId ORDER BY ProtocolCommandID ASC) as RowNum
, ProtocolCommandId
FROM ProtocolCommands) as first_conn ON pc.ProtocolCommandID = first_conn.ProtocolCommandID
GROUP BY CONVERT(date,pc.Time_stamp),pc.SiteName, pc.UserName, pc.Command, first_conn.RowNum