3

私のテーブルには次の構造が含まれています。

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 列に対してこれらの「仮想行」を作成する方法はわかりません。

たぶん、それはまったく不可能です。どんな助けでも大歓迎です!

4

3 に答える 3

3

あなたの最善の策は、Calendarテーブルを作成することです。

あなたの目的のために、必要なのは1つの列だけです...

CREATE TABLE Calendar AS (calendar_date DATE)

次に、関心のあるすべての日付をそのテーブルに入力します。100 年であっても、テーブルはまだ小さいままです。

その列を主キーとして追加することを忘れないでください。

その後、テーブルに参加するだけです...

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

後で、休日の日付、会計年度の境界などを知りたいと思うかもしれません。これらはすべて、追加フィールドおよびインデックスとしてそのカレンダー テーブルに追加できます。

クエリ内で面倒な日付ベースのルールを再計算するのではなく、キャッシュによく似ています。

または、データが ID であり、他の列がファクトであるディメンション テーブルと考えることができます。

于 2012-11-14T10:56:03.577 に答える
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 フィドルのデモ

于 2012-11-14T11:02:34.787 に答える
0

私はこれがオラクルで動作するというセバスに同意します..あなたのテーブル名を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;

メタテーブルにアクセスできる場合は、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

何か問題があればお知らせください。

于 2012-11-14T14:56:08.527 に答える