zac*_*ckm 5 sql-server t-sql sql-server-2008-r2
我有一个完整的网络接口统计表。
InterfaceID TimeStamp RCV_bps XMT_bps
----------- ------------------------------ ------------- -------------
275 Nov 19 2015 12:12AM 1785.593 8.859444
275 Nov 19 2015 12:21AM 1769.675 9.540664
275 Nov 19 2015 12:30AM 1826.036 10.22184
275 Nov 19 2015 12:39AM 1754.356 8.177711
275 Nov 19 2015 12:48AM 1820.504 7.496235
275 Nov 19 2015 12:57AM 1824.645 8.177948
275 Nov 19 2015 1:06AM 1795.941 8.177711
275 Nov 19 2015 1:15AM 1780.149 7.496235
275 Nov 19 2015 1:24AM 1817.059 8.177475
275 Nov 19 2015 1:33AM 1799.519 7.496452
275 Nov 19 2015 1:42AM 1840.726 8.177711
275 Nov 19 2015 1:51AM 3986.634 7.496235
275 Nov 19 2015 2:00AM 1886.375 8.177475
275 Nov 19 2015 2:09AM 1771.905 7.496019
275 Nov 19 2015 2:18AM 1803.834 8.769002
275 Nov 19 2015 2:27AM 1807.718 7.574132
275 Nov 19 2015 2:36AM 1788.274 8.859444
275 Nov 19 2015 2:45AM 1855.727 7.496452
275 Nov 19 2015 2:54AM 1826.8 7.496235
275 Nov 19 2015 3:03AM 1870.37 8.177711
Run Code Online (Sandbox Code Playgroud)
我需要将其加入另一个具有接口详细信息的表
InterfaceID InterfaceName DeviceName
----------- ------------- ----------
275 Ethernet-1 Router-A
Run Code Online (Sandbox Code Playgroud)
要求是生成一份报告,显示 RCV_bps 和 XMT_bps 的最大值,并显示它们发生的时间。
我知道我可以通过使用 datepart 函数分组来获取小时块。
SELECT
d.DeviceName
,d.InterfaceName
,r.maxRCV_hour
,r.maxRCV
,t.maxXMT_hour
,t.maxXMT
FROM Details d
INNER JOIN (
SELECT
InterfaceID
,datepart(hh, s.timestamp) maxRCV_hour
,MAX(RCV_bps) maxRCV
FROM Statistics s
WHERE TimeStamp > (GetDate()-1)
GROUP BY
InterfaceID
,datepart(hh, s.timestamp)
) r ON r.InterfaceID = d.InterfaceID
INNER JOIN (
SELECT
InterfaceID
,datepart(hh, s.timestamp) maxXMT_hour
,MAX(XMT_bps) maxXMT
FROM Statistics s
WHERE TimeStamp > (GetDate()-1)
GROUP BY
InterfaceID
,datepart(hh, s.timestamp)
) t ON t.InterfaceID = d.InterfaceID
Run Code Online (Sandbox Code Playgroud)
但是我看不到如何取这些值并只返回 rcv 和 xmt 的最大值。根据仅过去 1 天的上述时间限制,我在每个子查询中获得了 0 - 23 小时的 24 行数据......
子查询“r”:
InterfaceID maxRCV_hour maxRCV
----------- ----------- -------------
275 0 1826.036
275 1 3986.634
275 2 1886.375
275 3 1895.214
275 4 1874.77
275 5 3999.568
275 6 2322.544
275 7 3327.41
275 8 6931.27
275 9 9165.674
275 10 9548.88
275 11 7349.096
275 12 5908.13
275 13 7247.869
275 14 9452.746
275 15 7118.653
275 16 5124.106
275 17 4012.313
275 18 3444.12
275 19 1236.745
275 20 2314.144
275 21 3430.802
275 22 1307.774
275 23 1594.491
Run Code Online (Sandbox Code Playgroud)
子查询“t”:
InterfaceID maxXMT_hour maxXMT
----------- ----------- -------------
275 0 10.22184
275 1 8.177711
275 2 8.859444
275 3 12.26692
275 4 12.26657
275 5 12.26657
275 6 12.26657
275 7 8.859187
275 8 2969.632
275 9 13.60028
275 10 9.68881
275 11 8.177711
275 12 8.177711
275 13 7.496452
275 14 7.496452
275 15 8.177948
275 16 8.17783
275 17 8.859154
275 18 8.859444
275 19 8.859187
275 20 8.199979
275 21 8.859444
275 22 8.177761
275 23 8.859699
Run Code Online (Sandbox Code Playgroud)
但是当我运行完整的查询时,我得到 576 行(所以我加入事情的方式肯定是关闭的)
我想要的是 1 行数据,显示 RCV 和 XMT 端的最大值及其各自的小时数。
根据我在上述子查询中的结果,我希望最终结果如下所示:
DeviceName InterfaceName maxRCV_hour maxRCV maxXMT_hour maxXMT
---------- ------------- ----------- ------- ----------- --------
Router-A Ethernet-1 10 9548.88 8 2969.632
Run Code Online (Sandbox Code Playgroud)
我的假设是我需要使用 CTE 或窗口,但这些都超出了我目前的优势,我可以使用一些帮助来解决这个问题。
任何帮助是极大的赞赏!!!
您不一定需要使用 CTE 或窗口函数:有很多方法可以给这只猫剥皮。
这是我想到的最简单的:
-- SAMPLE DATA:
-- remember to post data this way next time you ask for help,
-- so that people don't have to do it for you
IF OBJECT_ID('tempdb..#statistics') IS NOT NULL
DROP TABLE #statistics;
GO
CREATE TABLE #statistics(
InterfaceID int NOT NULL
,TimeStamp DATETIME NOT NULL
,RCV_bps decimal(9,3) NOT NULL
,XMT_bps decimal(9,6) NOT NULL
);
INSERT INTO #statistics(InterfaceID,TimeStamp,RCV_bps,XMT_bps) VALUES ('275','Nov 20 2015 12:12AM','1785.593','8.859444');
INSERT INTO #statistics(InterfaceID,TimeStamp,RCV_bps,XMT_bps) VALUES ('275','Nov 20 2015 12:21AM','1769.675','9.540664');
INSERT INTO #statistics(InterfaceID,TimeStamp,RCV_bps,XMT_bps) VALUES ('275','Nov 20 2015 12:30AM','1826.036','10.22184');
INSERT INTO #statistics(InterfaceID,TimeStamp,RCV_bps,XMT_bps) VALUES ('275','Nov 20 2015 12:39AM','1754.356','8.177711');
INSERT INTO #statistics(InterfaceID,TimeStamp,RCV_bps,XMT_bps) VALUES ('275','Nov 20 2015 12:48AM','1820.504','7.496235');
INSERT INTO #statistics(InterfaceID,TimeStamp,RCV_bps,XMT_bps) VALUES ('275','Nov 20 2015 12:57AM','1824.645','8.177948');
INSERT INTO #statistics(InterfaceID,TimeStamp,RCV_bps,XMT_bps) VALUES ('275','Nov 20 2015 1:06AM','1795.941','8.177711');
INSERT INTO #statistics(InterfaceID,TimeStamp,RCV_bps,XMT_bps) VALUES ('275','Nov 20 2015 1:15AM','1780.149','7.496235');
INSERT INTO #statistics(InterfaceID,TimeStamp,RCV_bps,XMT_bps) VALUES ('275','Nov 20 2015 1:24AM','1817.059','8.177475');
INSERT INTO #statistics(InterfaceID,TimeStamp,RCV_bps,XMT_bps) VALUES ('275','Nov 20 2015 1:33AM','1799.519','7.496452');
INSERT INTO #statistics(InterfaceID,TimeStamp,RCV_bps,XMT_bps) VALUES ('275','Nov 20 2015 1:42AM','1840.726','8.177711');
INSERT INTO #statistics(InterfaceID,TimeStamp,RCV_bps,XMT_bps) VALUES ('275','Nov 20 2015 1:51AM','3986.634','7.496235');
INSERT INTO #statistics(InterfaceID,TimeStamp,RCV_bps,XMT_bps) VALUES ('275','Nov 20 2015 2:00AM','1886.375','8.177475');
INSERT INTO #statistics(InterfaceID,TimeStamp,RCV_bps,XMT_bps) VALUES ('275','Nov 20 2015 2:09AM','1771.905','7.496019');
INSERT INTO #statistics(InterfaceID,TimeStamp,RCV_bps,XMT_bps) VALUES ('275','Nov 20 2015 2:18AM','1803.834','8.769002');
INSERT INTO #statistics(InterfaceID,TimeStamp,RCV_bps,XMT_bps) VALUES ('275','Nov 20 2015 2:27AM','1807.718','7.574132');
INSERT INTO #statistics(InterfaceID,TimeStamp,RCV_bps,XMT_bps) VALUES ('275','Nov 20 2015 2:36AM','1788.274','8.859444');
INSERT INTO #statistics(InterfaceID,TimeStamp,RCV_bps,XMT_bps) VALUES ('275','Nov 20 2015 2:45AM','1855.727','7.496452');
INSERT INTO #statistics(InterfaceID,TimeStamp,RCV_bps,XMT_bps) VALUES ('275','Nov 20 2015 2:54AM','1826.8','7.496235');
INSERT INTO #statistics(InterfaceID,TimeStamp,RCV_bps,XMT_bps) VALUES ('275','Nov 20 2015 3:03AM','1870.37','8.177711');
GO
IF OBJECT_ID('tempdb..#details') IS NOT NULL
DROP TABLE #details;
GO
CREATE TABLE #details (
InterfaceID int NOT NULL,
InterfaceName varchar(50) NOT NULL,
DeviceName varchar(50) NOT NULL
);
INSERT INTO #details VALUES(275, 'Ethernet-1', 'Router-A');
GO
Run Code Online (Sandbox Code Playgroud)
。
-- POSSIBLE SOLUTION:
-- use CROSS APPLY TOP(1)/ORDER BY to find the value
SELECT
d.DeviceName
,d.InterfaceName
,r.maxRCV_hour
,r.maxRCV
,t.maxXMT_hour
,t.maxXMT
FROM #Details d
CROSS APPLY (
SELECT TOP(1)
InterfaceID
,datepart(hh, s.timestamp) maxRCV_hour
,MAX(RCV_bps) maxRCV
FROM #Statistics s
WHERE TimeStamp > (GetDate()-1)
GROUP BY
InterfaceID
,datepart(hh, s.timestamp)
HAVING s.InterfaceID = d.InterfaceID
ORDER BY maxRCV DESC
) AS r
CROSS APPLY (
SELECT TOP(1)
InterfaceID
,datepart(hh, s.timestamp) maxXMT_hour
,MAX(XMT_bps) maxXMT
FROM #Statistics s
WHERE TimeStamp > (GetDate()-1)
GROUP BY
InterfaceID
,datepart(hh, s.timestamp)
HAVING s.InterfaceID = d.InterfaceID
ORDER BY maxXMT DESC
) AS t;
Run Code Online (Sandbox Code Playgroud)