我有一张桌子,上面有这样的东西:
| 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,这是我目前正在使用的)相当陌生。如果是这样,我应该使用什么作为连接键?如果有人可以指导我完成整个过程,我将不胜感激。:) 预先感谢您的回答!
您可能有兴趣使用基于集合的方法而不是过程(基于循环)方法来学习一种有效的方法。
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,并且请不要对列名使用保留字
| 归档时间: |
|
| 查看次数: |
1036 次 |
| 最近记录: |