2

検索されている曜日に基づいて、テーブルから2つのレート列のうちの1つを選択しようとしています。このクエリに2つのテーブルを使用しようとしています。カレンダーテーブル(テーブル名=カレンダー、列名= caldates)は、各行が2012-06-30から2014-05-31までの日付である日付の厳密なリストです。 。また、start_date、end_date、weekday_rate、weekend_rateの4つの列を持つ別のテーブル(テーブル名= rate)があります。

Start_date      end_date     weekday_rate     weekend_rate
"2012-05-01"  "2012-06-30"        69              150
"2012-07-01"  "2012-08-31"        74              200
"2012-09-01"  "2012-11-14"        75              210
"2012-11-15"  "2013-01-31"        90              150

クエリが実行されると、システムは正しいレートを検索する必要があります。現在、私のクエリは次のようになっています。

SELECT  
    CASE cast(extract(dow from caldates) as int)
    WHEN '0'  then (select weekday_rate from rates)
    WHEN '1'  then (select weekday_rate from rates)
    WHEN '2'  then (select weekday_rate from rates)
    WHEN '3'  then (select weekday_rate from rates)
    WHEN '4'  then (select weekday_rate from rates)
    WHEN '5'  then (select weekend_rate from rates)
    When '6'  then (select weekend_rate from rates)
    End AS the_date_rate
FROM calendar WHERE caldates >= '2012-08-30' and  caldates <=  '2012-09-04' ;

クエリを実行すると、「エラー:式として使用されるサブクエリによって返される複数の行」というエラーが表示されます。

日付の範囲と日付に関連付けられたレートを出力に表示したいと思います。上記の例は次のようになります

caldates        the_date_rate
2012-08-30           74
2012-08-31           200
2012-09-01           210
2012-09-02           75
2012-09-03           75
2012-09-04           75

何か案は?

4

2 に答える 2

1

これは大幅に簡略化できます。

SELECT d.day
      ,CASE WHEN extract(isodow from d.day) < 6
         THEN weekday_rate
         ELSE weekend_rate
       END AS rate
FROM  (SELECT generate_series('2012-06-30'::date
                             ,'2014-05-31'::date, '1d'::interval)::date AS day
      ) d
LEFT   JOIN rates r ON d.day BETWEEN r.start_date AND r.end_date
ORDER  BY d.day

主なポイント

  • calendarPostgreSQL では、ギャップのない一連の日付のテーブルは必要ありません。generate_series()代わりに、デモンストレーションのように使用してください。

  • テーブルに参加する必要がありratesます。現在受け入れられている答えはまったく機能しません。

  • 私は を使用LEFT JOINしているので、レートが一致しない日でもNULLas rate の結果になります。

  • 現在受け入れられている回答では、日曜日を平日、金曜日を週末として扱います。これは期待されていないと思います。
    ステートメントは、CASEを使用する 2 つのケースだけで、はるかに単純にすることもできますextract(isodow FROM source)

  • extract()toの結果をキャストする必要はありませんinteger。比較するリテラルは、一致する型double precisionに自動的にキャストされます。

于 2012-09-13T05:09:25.927 に答える
0

これで十分です(when句の後の日付の値の前後に引用符が本当に必要かどうかも確認してください)。

SELECT  
    CASE 
        WHEN cast(extract(dow from caldates) as int) < 6  then weekday_rate
        ELSE weekend_rate
    End AS the_date_rate
FROM 
    calendar 
WHERE 
    caldates >= '2012-08-30' and  caldates <=  '2012-09-04' ;
于 2012-09-13T02:30:30.047 に答える