说,我有一个包含 C 列和 N 行的表格。我想生成一个select语句,表示该表的“连接”,其数据范围包含 M 天。结果集应包含 C + 1 列(最后一个是日期)和 NXM 行。
澄清事情的简单例子: 鉴于以下表格 A :
select * from A;
avalue |
--------+
"a" |
日期范围从2012年10月10日到12日,我想要以下结果集:
avalue | date
--------+-------
"a" | 2012-10-10
"a" | 2012-10-11
"a" | 2012-10-12
(这是我在最终计算任何一天的库存水平时需要的垫脚石,给定起始值和增量)
答案 0 :(得分:9)
Postgres 方式很简单:CROSS JOIN
到函数generate_series()
:
SELECT t.*, g.day::date
FROM tbl t
CROSS JOIN generate_series(timestamp '2012-10-10'
, timestamp '2012-10-12'
, interval '1 day') AS g(day);
准确生成所请求的输出。
generate_series()
是一个生成派生表的set-returns函数(a.k.a。“table function”)。有几个重载变体,这就是我选择timestamp
输入的原因:
对于任意日期,请将generate_series()
替换为VALUES
表达式。无需坚持表:
SELECT *
FROM tbl t
CROSS JOIN (
VALUES
(date '2012-08-13') -- explicit type in 1st row
, ('2012-09-05')
, ('2012-10-10')
) g(day);
答案 1 :(得分:2)
如果日期表中包含的日期多于您感兴趣的日期,请执行
select a.avalue, b.date from a, b where b.date between '2012-10-10' and '2012-10-12'
另外明智的是,如果日期表只包含您感兴趣的日期,则笛卡尔联接将实现此目的:
select * from a,b;
答案 2 :(得分:1)
declare
@Date1 datetime = '20121010',
@Date2 datetime = '20121012';
with Dates
as
(
select @Date1 as [Date]
union all
select dateadd(dd, 1, D.[Date]) as [Date]
from Dates as D
where D.[Date] <= DATEADD(dd, -1, @Date2)
)
select
A.value, D.[Date]
from Dates as D
cross join A
答案 3 :(得分:1)
对于MySQL
架构/数据:
CREATE TABLE someTable
(
someCol varchar(8) not null
);
INSERT INTO someTable VALUES ('a');
CREATE TABLE calendar
(
calDate datetime not null,
isBus bit
);
ALTER TABLE calendar
ADD CONSTRAINT PK_calendar
PRIMARY KEY (calDate);
INSERT INTO calendar VALUES ('2012-10-10', 1);
INSERT INTO calendar VALUES ('2012-10-11', 1);
INSERT INTO calendar VALUES ('2012-10-12', 1);
查询:
select s.someCol, c.calDate from someTable s, calendar c;
答案 4 :(得分:1)
你真的有两个选择你想做什么。
如果你的RDBMS支持它(我知道SQL Server有,但我不知道其他任何人),你可以创建一个table-valued function,它接收一个日期范围并返回一个结果集该范围内的离散日期。您可以在表格和函数之间进行笛卡尔连接。
您可以创建日期值的静态表,然后在两个表之间进行笛卡尔连接。
第二个选项的效果会更好,尤其是在处理大日期范围时,该解决方案将无法处理任意日期范围。但是,您应该知道自己的最短约会日期,随着时间的推移,您可以随时在桌面上添加更多日期。
答案 5 :(得分:0)
我对你的M桌不是很清楚。如果你有这样一个带有日期的表(M),那么在交叉连接之后会产生结果。
SELECT C.*, M.date FROM C CROSS JOIN M