使用基于集合的方法

时间:2017-10-08 06:18:04

标签: sql sql-server

我能够在两个日期之间获得所有这些日子。

DECLARE @MinDate DATE = '20140101' ,
        @MaxDate DATE = '20140106';

SELECT TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1)
    DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY a.object_id) - 1, @MinDate)
FROM    
    sys.all_objects a
CROSS JOIN 
    sys.all_objects b

现在我得到了这样的结果集:

-----------------------------------------------------------
| ID  |      StartDate          |         EndDate         |
-----------------------------------------------------------
|  1  | 2017-05-12 00:00:00.000 | 2017-05-15 00:00:00.000 |
|  2  | 2018-08-10 00:00:00.000 | 2018-08-13 00:00:00.000 |
|  3  | 2019-02-12 00:00:00.000 | 2019-02-13 00:00:00.000 |
-----------------------------------------------------------

我需要找到此表中所有开始日期和结束日期之间的所有日期,预期结果应如下所示:

---------------------------
|        AllDates         |
---------------------------
| 2017-05-12 00:00:00.000 |
| 2017-05-13 00:00:00.000 |
| 2017-05-14 00:00:00.000 |
| 2017-05-15 00:00:00.000 |
| 2018-08-10 00:00:00.000 | 
| 2018-08-11 00:00:00.000 | 
| 2018-08-12 00:00:00.000 | 
| 2018-08-13 00:00:00.000 |
| 2019-02-12 00:00:00.000 | 
| 2019-02-13 00:00:00.000 |
---------------------------

在SQL Server中不使用用户定义的函数,只能通过使用基于集合的方法来实现吗?

2 个答案:

答案 0 :(得分:2)

您可以使用以下查询:

set = frame[['block_number', 'block_header']]
        .groupby(['block_number'])['block_header'].agg('unique')

这会将原始查询的相同逻辑应用于您的表。

注意:您必须对交叉加入;WITH Tally AS ( SELECT TOP 365 ROW_NUMBER() OVER ( ORDER BY a.object_id ) - 1 AS rn FROM sys.all_objects a CROSS JOIN sys.all_objects b ) SELECT StartDate, EndDate, DATEADD(DAY, t.rn, StartDate) AS AllDates FROM mytable CROSS APPLY (SELECT DATEDIFF(DAY, StartDate, EndDate) + 1) AS c(days) JOIN Tally AS t ON t.rn + 1 <= c.days ORDER BY StartDate, AllDates 返回的行数使用限制,否则查询效率会降低。如果sys.all_objectsStartDate之间的差异始终小于一年,那么您可以使用EndDate作为限制。

答案 1 :(得分:0)

请使用计数表,如下面的代码

您可以使用以下代码填写统计表

SELECT TOP 1000000 N=IDENTITY(INT, 1, 1)
INTO dbo.Tally1K
FROM master.dbo.syscolumns a CROSS JOIN master.dbo.syscolumns  b;

ALTER TABLE dbo.Tally1K ADD CONSTRAINT NBR_pk PRIMARY KEY(N);

现在使用此计数表填写我们的日期。

select DATEADD(DAY, t.N - 1, CONVERT(datetime, '02/25/2014'))
from Tally1K t
where t.N < DATEDIFF(DAY, '02/24/2014', '04/26/2014') + 1
order by 1;

有关计数表的更多信息,请转到下面的链接

http://www.sqlservercentral.com/blogs/dwainsql/2014/03/27/tally-tables-in-t-sql/