我的表包含以下结构:
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列创建这些“虚拟行”。
也许根本不可能。非常感谢任何帮助!
答案 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)
答案 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
如果您有任何问题,请告诉我。