T-SQL:选择带有子节点的前20个根节点

时间:2013-12-07 09:30:22

标签: sql sql-server sql-server-2012

我的情况:我在SQL Server 2012数据库中有一个表

id | created             | sum
------------------------------
1  | 2013-12-10 12:00:00 | 200 
2  | 2013-12-10 13:00:00 | 300 
3  | 2013-12-10 14:00:00 | 400 
4  | 2013-12-09 08:00:00 | 100 
5  | 2013-12-09 15:00:00 | 600 
6  | 2013-12-10 12:00:00 | 50 
...
50 | 2013-11-23 14:00:00 | 400 
51 | 2013-11-22 08:00:00 | 100 
52 | 2013-11-22 15:00:00 | 600 
53 | 2013-11-20 12:00:00 | 50 

如何选择20个不同日期的行而不考虑时间

选择操作的预期结果:

1 | 2013-12-10
1  | 2013-12-10 12:00:00 | 200 
2  | 2013-12-10 13:00:00 | 300 
3  | 2013-12-10 14:00:00 | 400 
2 | 2013-12-09
4  | 2013-12-09 08:00:00 | 100 
5  | 2013-12-09 15:00:00 | 600 
...
20| 2013-11-22
51 | 2013-11-22 08:00:00 | 100 
52 | 2013-11-22 15:00:00 | 600 

3 个答案:

答案 0 :(得分:1)

您可以尝试这样的事情:

  • 让CTE(公用表格表达式)从表格中提取20个仅限日期的值
  • 将您的基表与CTE输出连接,以获取基表中的所有行,仅适用于所选日期

尝试这样的事情:

-- replace this with your own, base table - this is just for demo purposes
DECLARE @table TABLE (ID INT, Created DATETIME2(0), ValueSum INT)

INSERT INTO @table VALUES(1, '2013-12-10 12:00:00', 200), 
(2, '2013-12-10 13:00:00', 300 ), 
(3, '2013-12-10 14:00:00', 400),  
(4, '2013-12-09 08:00:00', 100 ), 
(5, '2013-12-09 15:00:00', 600),  
(6, '2013-12-10 12:00:00', 50),  
(50, '2013-11-23 14:00:00', 400 ), 
(51, '2013-11-22 08:00:00', 100 ), 
(52, '2013-11-22 15:00:00', 600 ), 
(53, '2013-11-20 12:00:00', 50 )

-- define a CTE thta selects TOP (n) distinct date-only values from your base table    
;WITH RandomDates AS
(
    SELECT DISTINCT TOP (3)
        DateOnly = CAST(Created AS DATE)
    FROM @table
)
SELECT * FROM RandomDates

这将列出您选择的仅限日期值

如果您将这些值与基表相加,则可能需要输出...

;WITH RandomDates AS
(
    SELECT DISTINCT TOP (20)
        DateOnly = CAST(Created AS DATE)
    FROM dbo.YourBaseTable
)
SELECT t.* 
FROM RandomDates rd
INNER JOIN dbo.YourBaseTable t ON CAST(t.Created AS DATE) = rd.DateOnly

答案 1 :(得分:0)

试试这个:

SELECT rowNo, createdDate, sumCol
FROM ( SELECT TOP 20 ROW_NUMBER() OVER (ORDER BY CONVERT(DATE, a.created)) rowNo, CONVERT(DATE, a.created) createdDate, '' sumCol
       FROM tableA a
       GROUP BY CONVERT(DATE, a.created)
       UNION 
       SELECT B.id AS rowNo, b.created AS createdDate, b.sum AS sumCol
       FROM (SELECT TOP 20 CONVERT(DATE, a.created) createdDate FROM tableA a ORDER BY CONVERT(DATE, a.created)) A
       INNER JOIN tableA B ON A.createdDate = CONVERT(DATE, b.created)
      ) AS A
ORDER BY createdDate

检查SQL FIDDLE DEMO

<强>输出

| ROWNO |         CREATEDDATE | SUMCOL |
|-------|---------------------|--------|
|     1 | 2013-11-20 00:00:00 |      0 |
|    53 | 2013-11-20 12:00:00 |     50 |
|     2 | 2013-11-22 00:00:00 |      0 |
|    51 | 2013-11-22 08:00:00 |    100 |
|    52 | 2013-11-22 15:00:00 |    600 |
|     3 | 2013-11-23 00:00:00 |      0 |
|    50 | 2013-11-23 14:00:00 |    400 |
|     4 | 2013-12-09 00:00:00 |      0 |
|     4 | 2013-12-09 08:00:00 |    100 |
|     5 | 2013-12-09 15:00:00 |    600 |
|     5 | 2013-12-10 00:00:00 |      0 |
|     1 | 2013-12-10 12:00:00 |    200 |
|     6 | 2013-12-10 12:00:00 |     50 |
|     2 | 2013-12-10 13:00:00 |    300 |
|     3 | 2013-12-10 14:00:00 |    400 |

答案 2 :(得分:0)

试试这个

select top 20 distinct CONVERT(varchar(25), Created, 110)
from    tbl
where   CONVERT(varchar(25), Created, 110) between [Datfrom] and [DateTo]

更快

select top 10 distinct CONVERT(varchar(25), Created, 110)
from    tbl
where   Created between '1/1/2013' + ' 00:00:00' and '1/31/2013' + ' 23:59:59'