基于现有表生成时间序列

use*_*974 2 sql-server

我有一张桌子,上面有这样的东西:

|    Zip    |     Population    |
+-----------+-------------------+
|    00001  |     100           |
|    00002  |     200           |
|    00003  |     250           |
Run Code Online (Sandbox Code Playgroud)

等等。我想从上表生成一个新表,它看起来像这样:

|    Date       |    Zip    |     Population    |
+---------------+-----------+-------------------+
|    01-01-2016 |   00001   |     100           |
|    01-02-2016 |   00001   |     100           |
|    01-03-2016 |   00001   |     100           |
|    ...        |   00001   |     100           |
|    31-12-2016 |   00001   |     100           |
|    01-01-2016 |   00002   |     200           |
|    01-02-2016 |   00002   |     200           |
|    01-03-2016 |   00002   |     200           |
|    ...        |   00002   |     200           |
|    31-12-2016 |   00002   |     200           |
Run Code Online (Sandbox Code Playgroud)

对顶部原始表中的所有行依此类推。

我已经找到一种方法来生成一个特定范围之间的日期(例如,概述这里)。我也认为我应该用它LEFT JOIN来实现那个??我对 SQL(或 SQL Server,这是我目前正在使用的)相当陌生。如果是这样,我应该使用什么作为连接键?如果有人可以指导我完成整个过程,我将不胜感激。:) 预先感谢您的回答!

Han*_*non 5

您可能有兴趣使用基于集合的方法而不是过程(基于循环)方法来学习一种有效的方法。

SQL Server 通常执行基于集合的操作比过程操作快得多。

下面的代码显示了如何使用select语句生成 366 行,其中包含从 2016-01-01 到 2016-12-31(2016 年是闰年)的日期。然后,我们使用CROSS JOIN.

首先,我们用你的表和一个新的目标表设置一个测试台:

USE tempdb;

IF OBJECT_ID('dbo.Zips') IS NOT NULL
DROP TABLE dbo.Zips;
CREATE TABLE dbo.Zips
(
    Zip VARCHAR(5) NOT NULL
    , Pop INT NOT NULL
);

INSERT INTO dbo.Zips (Zip, Pop)
VALUES ('00001', 100)
    , ('00002', 200)
    , ('00003', 250);

IF OBJECT_ID('dbo.ZipsWithDates') IS NOT NULL
DROP TABLE dbo.ZipsWithDates;
CREATE TABLE dbo.ZipsWithDates
(
    Zip VARCHAR(5) NOT NULL
    , Pop INT NOT NULL
    , ZipDate DATE NOT NULL
);
Run Code Online (Sandbox Code Playgroud)

这将为 中的每一行插入行,一年中的每一天都有一个行Zips

;WITH dates AS (
SELECT TOP(366) /* 366 days in a leap-year, which 2016 is */
    TheDate = DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY o1.object_id, o2.object_id), CONVERT(DATE, N'2015-12-31'))
FROM sys.objects o1
    CROSS JOIN sys.objects o2
)
INSERT INTO dbo.ZipsWithDates (Zip, Pop, ZipDate)
SELECT z.Zip
    , z.Pop
    , d.TheDate
FROM dates d
    CROSS JOIN dbo.Zips z
Run Code Online (Sandbox Code Playgroud)

这显示了新表的内容:

SELECT *
FROM dbo.ZipsWithDates;
Run Code Online (Sandbox Code Playgroud)

这是前几行的输出显示:

在此处输入图片说明

请注意,您应该始终指定 schema,并且请不要对列名使用保留字