2

私たちのデータベースには、過去 2 年間のモデルのデータがあります。過去 2 四半期のデータベース テーブルからこれらのモデルのみを選択したいと考えています。

仮定する、Sysdate-> 29/07/2013(July)

四半期以下の月からモデルを取得できるはずです

Q1-April,May,June(last quarter)

Q2-July,Aug,Sep(Including quarter)

以下のクエリはどのように変更する必要がありますか?

Select model_id,model_name,Effective_date_from,effective_date_to 
from   model 
where active='YES';
4

3 に答える 3

7

アップデート

オラクルの場合:

FROM mytable t
JOIN ( SELECT ADD_MONTHS(TRUNC(SYSDATE,'Q'),3) AS b
            , ADD_MONTHS(TRUNC(SYSDATE,'Q'),-3) AS e
         FROM DUAL
     ) dr
  ON NOT ( t.effective_date_from >= dr.e OR t.effective_date_to < dr.b )
  OR ( t.effective_date_from IS NULL AND t.effective_date_to IS NULL )

MySQL の場合:

FROM mytable t
JOIN ( SELECT MAKEDATE(YEAR(NOW()),1) + INTERVAL QUARTER(NOW())-2 QUARTER AS b
            , MAKEDATE(YEAR(NOW()),1) + INTERVAL QUARTER(NOW())-0 QUARTER AS e
     ) dr
  ON NOT ( t.effective_date_from >= dr.e OR t.effective_date_to < dr.b )
  OR ( t.effective_date_from IS NULL AND t.effective_date_to IS NULL )

slOppy からの回答を確認し、質問を再度確認した後、2 つの日付列と がeffective_date_fromあり、と日付の値の間の任意の時点にあるeffective_date_to行をおそらく取得したいと考えていることを考慮していないことに気付きました。指定された日付範囲内の任意の時刻 (前四半期の初めから次の四半期の初めまで)。fromto

簡単にするために (今のところ)、発効日がfrom < to.

drb考えられるケースは、(大雑把に) 次のように表すことができdreます。 ~の間の発効日effective_date_fromedfeffective_date_toedtedfedt

      drb     dre
<--->  |       |              case 1: edt < drb
   <---|---->  |              case 2: drb between edf and edt
    <--|-------|---->         case 3: edf < drb AND edt > dre
       | <---> |              case 4: edf > drb AND edt < dre
       |    <--|--->          case 5: edf between drb and dre AND edt > dre
       |       |  <--->       case 6: edf > dre
       |       |
   <--->       |              case e1: edt = drb
    <--|------->              case e2: edf > drb AND edt = dre
       <--->   |              case e3: edf = drb and edt < dre
       <------->              case e4: edf = drb and edt = dre
       <-------|-->           case e5: edf = drb and edt > dre
       |   <--->              case e6: edf > drb AND edt = dre
       |       <--->          case e7: edf = dre

ケース 2 から 5 およびエッジ ケース e1 から e6 を満たす行を返すように求めていると思います。これは、ケース 1、6、および e7 を除くすべてのケースです。

ケース 1 とケース 6 をテストし、それを否定する述語を書くことができれば、あなたの望む結果が得られるはずです。このようなもの:

時間コンポーネントを考慮して日時を処理するには:

  WHERE NOT ( effective_date_to < drb OR effective_date_from >= dre )

(生成する式drbdre(日付範囲の開始と日付範囲の終了)は、元の回答に示されています。)

effective_date_fromとの両方が NULL である行も返すにeffective_date_toは、そのケースを処理する別の条件を追加できます。

インライン ビューを使用してこれらの式を提供すると、回答の先頭に SQL が表示されます。

私は以前、次のような変わったケースを棚上げしましたeffective_date_from > effective_date_to。それらの行が有効かどうか、およびそれらが返される条件を把握する必要があります。


元の答え:

これは、 OracleMySQLの両方で実現できます。私が使用するアプローチは、現在の日付を基準にして、各四半期の「開始日」を最初に生成することです。これらの日付値 (または日付値を返す式) を述語で参照できます。

MySQLで四半期の「開始日」を導出するには、関数を利用できQUARTER()ます。(この関数は、指定された DATE 値から 1 ~ 4 の整数値を返します。YEARおよび MAKEDATE 関数と組み合わせて、次のように、現在のシステム日付から各四半期の「開始日」を生成できます。

SELECT MAKEDATE(YEAR(NOW()),1) + INTERVAL QUARTER(NOW())-0 QUARTER AS next_q
     , MAKEDATE(YEAR(NOW()),1) + INTERVAL QUARTER(NOW())-1 QUARTER AS this_q
     , MAKEDATE(YEAR(NOW()),1) + INTERVAL QUARTER(NOW())-2 QUARTER AS prev_q

       next_q      this_q      prev_q      
       ----------  ----------  ------------
       2013-10-01  2013-07-01  2013-04-01  

これらの日付値を取得したら、それは簡単です。特定の日付列 (mydate次の例) の値が前四半期または現在の四半期内にある行のみを取得するには、その日付列を上記の 2 つの式と比較するだけです。

WHERE mydate >= MAKEDATE(YEAR(NOW()),1) + INTERVAL QUARTER(NOW())-2 QUARTER
  AND mydate <  MAKEDATE(YEAR(NOW()),1) + INTERVAL QUARTER(NOW())-0 QUARTER

Oracleでは、アプローチは同じです。違いは、相対的な四半期の開始日を導き出す方法にあります。Oracle では、次のような式を使用できます。

-- ALTER SESSION SET nls_date_format = 'YYYY-MM-DD'; 

SELECT ADD_MONTHS(TRUNC(SYSDATE,'Q'),3) AS next_q
     , ADD_MONTHS(TRUNC(SYSDATE,'Q'),0) AS this_q
     , ADD_MONTHS(TRUNC(SYSDATE,'Q'),-3) AS prev_q
  FROM DUAL

        NEXT_Q      THIS_Q      PREV_Q
        ----------  ----------  ------------
        2013-10-01  2013-07-01  2013-04-01  

したがって、 の値がmydate現在または前の四半期にある行を取得するには、列をこれらの式の 2 つと比較します。

WHERE mydate >= ADD_MONTHS(TRUNC(SYSDATE,'Q'),-3)
  AND mydate <  ADD_MONTHS(TRUNC(SYSDATE,'Q'),3)

(前の四半期の開始日以降で、次の四半期の開始日未満)。


これらの「開始日」を使用する少し異なる方法は、インライン ビューを使用して日付の値を返すことです。これにより、テストできる別のクエリが得られ、式に列名を割り当てることができます。drここでは、インライン ビューにエイリアス (日付範囲) を使用します。

オラクル

FROM mytable t
JOIN ( SELECT ADD_MONTHS(TRUNC(SYSDATE,'Q'),3) AS bd_next_qtr
            , ADD_MONTHS(TRUNC(SYSDATE,'Q'),-3) AS bd_prev_qtr
         FROM DUAL
     ) dr
  ON t.mydate >= dr.bd_prev_qtr
 AND t.mydate <  dr.bd_next_qtr

MySQL

FROM mytable t
JOIN ( SELECT MAKEDATE(YEAR(NOW()),1) + INTERVAL QUARTER(NOW())-2 QUARTER AS bd_next_qtr
            , MAKEDATE(YEAR(NOW()),1) + INTERVAL QUARTER(NOW())-0 QUARTER AS bd_prev_qtr
     ) dr
  ON t.mydate >= dr.bd_prev_qtr
 AND t.mydate <  dr.bd_next_qtr
于 2013-07-29T18:41:13.717 に答える
1

試しましたか:

SELECT
    * 
FROM
    yourTable
WHERE 
    yourDate  >= DATE_FORMAT( CURRENT_DATE - INTERVAL 3 MONTH, '%Y/%m/01' ) 
AND
    yourDate  < DATE_FORMAT( CURRENT_DATE- INTERVAL 1 MONTH, '%Y/%m/01');
于 2013-07-29T18:10:29.007 に答える