SQL Server 2008R2 - 最大结果和每天小时

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 或窗口,但这些都超出了我目前的优势,我可以使用一些帮助来解决这个问题。

任何帮助是极大的赞赏!!!

spa*_*dba 2

您不一定需要使用 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)