2017-10-27 17 views
0

同じ会計年度のデータ変更を制限するためのトリガー制限を作成する際、2つの日付(NEW.starting_date & OLD.starting_date)が同じ会計年度にあるかどうか、つまり自分の条件セクションにないかどうかを確認する必要がありました。SQL条件で2つの日付が同じ会計年度にあることを確認しますか?

私のテーブルはこのようになります。

pid (int) | data (varchar)  | starting_date (date) 

1    |   abc   | 2017-09-08 
2    |   def   | 2017-03-13 
3    |   ghi   | 2017-07-12 

条件

NEW.data<>OLD.data 
    AND (
     (YEAR(NEW.starting_date) = YEAR(OLD.starting_date) 
AND MONTH(NEW.starting_date)<=4 AND MONTH(OLD.starting_date) <=4 
AND MONTH(NEW.starting_date)>=3 AND MONTH(OLD.starting_date) >=3) 

OR 

(ABS(YEAR(NEW.starting_date)-YEAR(OLD.starting_date)) = 1 
AND MONTH(NEW.starting_date)<=3 AND MONTH(OLD.starting_date) >=4 
AND MONTH(NEW.starting_date)>=4 AND MONTH(OLD.starting_date) <=3) 
) 

                          ) 

注:会計年度は、毎年4月1日に開始します。

QUESTION:予想通り

  1. この状態は動作しません。何が問題なの?
  2. これを実行する他の効率的な方法はありますか?

データベースサーバー

Server: 127.0.0.1 via TCP/IP 
Server type: MariaDB 
Server version: 10.1.25-MariaDB - mariadb.org binary distribution 
Protocol version: 10 
User: [email protected] 
Server charset: UTF-8 Unicode (utf8) 

Webサーバー

Apache/2.4.26 (Win32) OpenSSL/1.0.2l PHP/5.6.31 
Database client version: libmysql - mysqlnd 5.0.11-dev - 20120503 - $Id: 76b08b24596e12d4553bd41fc93cccd5bac2fe7a $ 
+0

もう少し情報が必要です。利用されている特定のRDBMSを含めてください(MySQLには、タグが与えられているものとしますが、テキストで確認してください)、関係するテーブルのスキーマ、および期待どおりに動作しないものを示す完全な例を含めてください。 [構造化問合せ言語(SQL)の問合せのヒント](https://meta.stackoverflow.com/questions/271055/tips-for-asking-a-good-structured-query-language-sql-question)を読むことを検討してください。/271056)。 – hunteke

+0

@hunteke infoは –

+0

が追加されました。しかし、我々はまだ他の詳細が必要です:1)関連するテーブルのスキーマ、2)あなたが試みた特定のコード3)あなたが意図したとおりに動作していないものを正確に示す出力。 – hunteke

答えて

1

でこれらの値を比較する - なぜ期待通りに動作していないあなたの状態です。両方の日付が同じ年にある最初の部分では、3月と4月だけを比較しています。そして、第二部は、直前と来年誤って混入されて - あなたは2つのOR条件

にABSとスプリットを取り除くために必要があり

修正:

NEW.data<>OLD.data 
AND 
(
    (
     YEAR(NEW.starting_date) = YEAR(OLD.starting_date) 
     AND 
     ( 
     (MONTH(NEW.starting_date)<=3 AND MONTH(OLD.starting_date)<=3) 
     OR 
     (MONTH(NEW.starting_date)>=4 AND MONTH(OLD.starting_date)>=4) 
    ) 
    ) 
    OR 
    (
     YEAR(NEW.starting_date)-YEAR(OLD.starting_date) = 1 
     AND 
     MONTH(NEW.starting_date)<=3 AND MONTH(OLD.starting_date) >=4 
    ) 
    OR 
    (
     YEAR(NEW.starting_date)-YEAR(OLD.starting_date) = -1 
     AND 
     MONTH(NEW.starting_date)>=4 AND MONTH(OLD.starting_date) <=3 
    ) 
) 

EDIT - 質問の第二部のための - より効率的なサミュエルBantiの回答に基づいてこれを行う方法は、CASE文に変換:

NEW.data<>OLD.data 
AND CASE WHEN MONTH(NEW.starting_date) >= 4 
      THEN YEAR(NEW.starting_date) ELSE YEAR(NEW.starting_date) - 1 
    END 
= CASE WHEN MONTH(OLD.starting_date) >= 4 
      THEN YEAR(OLD.starting_date) ELSE YEAR(OLD.starting_date) - 1 
    END 
+0

あなたの答えは正しいです、あなたはちょうどあなたの第1の解決策でいくつかの括弧を逃しました –

+0

実際にはいくつかの追加があった:)今修正 –

0

あなたはあなたの日付のいずれかの年を抽出して、開始日または終了日を取得するために-04-01を追加することができます現在の会計年度の

DATE(DATE_ADD(CONCAT(YEAR(NEW.starting_date),'-','04-01'), INTERVAL 1 YEAR)) 
// OR 
DATE(DATE_SUB(CONCAT(YEAR(NEW.starting_date),'-','04-01'), INTERVAL 1 YEAR)) 

はその後、質問の最初の部分についてOLD.starting_date

2

私は今のフィルターでテストを行うが、ここでは2つの日付の会計年度の間に簡単な比較だことはできません。

SET @start_date = '2016-03-11'; 
SET @end_date = '2016-04-11'; 
SELECT IF(
(SELECT IF(MONTH(@start_date)>=4, YEAR(@start_date), YEAR(@start_date)-1)) 
= 
(SELECT IF(MONTH(@end_date)>=4, YEAR(@end_date), YEAR(@end_date)-1)) 
, 'Same fiscal year', 'Different fiscal year'); 
関連する問題