MySQL SELECT TMP行 - 开始日期和结束日期之间的日期

时间:2012-11-14 10:38:01

标签: mysql sql date

我的表包含以下结构:

START_DATE | END_DATE   | COST
2012-11-01 | 2012-11-05 | 500.5

我想执行一个返回以下结果的SELECT语句:

DATE       | COST
2012-11-01 | 100.1
2012-11-02 | 100.1
2012-11-03 | 100.1
2012-11-04 | 100.1
2012-11-05 | 100.1

我可以弄清楚如何将总费用除以开始日期和结束日期之间的天数,但不知道如何为DATE列创建这些“虚拟行”。

也许根本不可能。非常感谢任何帮助!

3 个答案:

答案 0 :(得分:3)

最好的办法是创建一个Calendar表。

出于您的目的,您只需要一列......

CREATE TABLE Calendar AS (calendar_date DATE)

然后你用那些你会感兴趣的日期填写那张桌子。即使它是一百年,桌子仍然很小。

请记得将该列添加为主键。

然后你就加入桌面......

SELECT
  *
FROM
  yourTable
INNER JOIN
  calendar
    ON  calendar.calendar_date >= yourTable.start_date
    AND calendar.calendar_date <= yourTable.end_date

稍后您可能会发现您想知道假期,财政年度边界等的日期。这些都可以作为添加字段和索引添加到该日历表中。

它非常像缓存,而不是在查询中重新计算基于日期的混乱规则。

或者,您可以将其视为维度表,其中数据是ID,其他列是事实。

答案 1 :(得分:2)

我同意 Dems 有一个日历表,这是最好的选择。因为Mysql没有像许多其他RDBMS那样的ROW_NUMBER函数。

另一个选项是创建一个包含序列号的表。您可以使用相当多的值(例如1到100k)填充此表,您认为这是任何start_date和end_date之间的最大天数

类似

create table seq

(rn int);

insert into seq
select 0 as rn union all
select 1 as rn union all
select 2 as rn union all
select 3 as rn union all
select 4 as rn union all
select 5 as rn 

然后运行以下查询:

select DATE_ADD(START_DATE, INTERVAL rn day) ,
       COST/(select datediff(END_DATE,START_DATE)+1 from table1)
from Table1
cross join seq
where rn<=(select datediff(END_DATE,START_DATE) from table1)


SQL fiddle demo

答案 2 :(得分:0)

我同意你的看法,这个人在甲骨文工作。 将您的tablename放在table1的位置

如果您无法访问all_objects,那么

select ( I +START_DATE-1) date1,cost/((END_DATE-START_DATE)+1) cost from table1 ,(     select I  from DUAL
              model
              dimension by (1 i)
              measures (0 X)
              (X[for I from 2 to 10000 increment 1] = 0)) 
              where END_DATE>=I +START_DATE-1;

如果您有权访问metatable all_objects,请尝试使用此

SELECT DATE1.DATE_ALL, table1.cost/((table1.END_DATE-table1.START_DATE)+1) NEW_COST 
FROM table1 INNER JOIN 
    (
     SELECT START_DATE + rownum-1 DATE_ALL 
     FROM ALL_OBJECTS
             CROSS JOIN table1
     WHERE 
         START_DATE + rownum - 1 <= (SELECT MAX(END_DATE) FROM table1)
    ) DATE1 ON table1.END_DATE >= DATE1.DATE_ALL

如果您有任何问题,请告诉我。