6

比如说,我有一个包含C列和N行的表。我想生成一个选择语句,表示该表的“连接”,数据范围包括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

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

4

6 回答 6

10

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()是一个产生派生表的集合返回函数(又名“表函数”)。有几个重载的变体,这就是我选择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);
于 2012-10-15T16:49:11.903 回答
2

如果日期表中的日期多于您感兴趣的日期,则执行

select a.avalue, b.date from a, b where b.date between '2012-10-10' and '2012-10-12'

否则,如果日期表仅包含您感兴趣的日期,笛卡尔连接将完成此操作:

select * from a,b;
于 2012-10-15T16:00:13.890 回答
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;
于 2012-10-15T16:09:08.667 回答
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
于 2012-10-15T16:07:38.037 回答
1

对于您要尝试做的事情,您确实有两种选择。

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

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

第二个选项的效果会更好,尤其是在处理较大的日期范围时,但是,该解决方案将无法处理任意日期范围。但是,您应该知道您的最短日期,并且随着时间的推移,您总是可以在表格中添加更多日期。

于 2012-10-15T16:16:49.663 回答
0

我对你的 M 表不是很清楚。假设您有这样一个带日期的表(M),则交叉连接将带来结果。

SELECT C.*, M.date FROM C CROSS JOIN M
于 2012-10-15T16:07:43.677 回答