带有日期范围的SQL JOIN表

时间:2012-10-15 15:54:45

标签: sql postgresql date

说,我有一个包含 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

(这是我在最终计算任何一天的库存水平时需要的垫脚石,给定起始值和增量)

6 个答案:

答案 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)

你真的有两个选择你想做什么。

  1. 如果你的RDBMS支持它(我知道SQL Server有,但我不知道其他任何人),你可以创建一个table-valued function,它接收一个日期范围并返回一个结果集该范围内的离散日期。您可以在表格和函数之间进行笛卡尔连接。

  2. 您可以创建日期值的静态表,然后在两个表之间进行笛卡尔连接。

  3. 第二个选项的效果会更好,尤其是在处理大日期范围时,该解决方案将无法处理任意日期范围。但是,您应该知道自己的最短约会日期,随着时间的推移,您可以随时在桌面上添加更多日期。

答案 5 :(得分:0)

我对你的M桌不是很清楚。如果你有这样一个带有日期的表(M),那么在交叉连接之后会产生结果。

SELECT C.*, M.date FROM C CROSS JOIN M