0

私は次のテーブルを持っています:

discount table:
id
name
description
amount

discount_exception
id
from_date
to_date
discount_id (foreign key to discount table)

割引例外テーブルは、ユーザーが割引を利用できないため表示すべきでない日付範囲を格納するために使用されます。discountとdiscount_exceptionの間には1:Mの関係があることに注意してください。つまり、1つの割引には多くの例外があります。

今のところ、SQLを記述した方法は、すべての割引を取得し、それらを配列でループし、discount_exceptionテーブルをクエリして、各割引が特定の日付範囲内にあるかどうかを確認することです。1回のデータベース呼び出しで、指定された日付範囲内の例外日付を持たないすべての割引を取得できるように、SQLを変更したいと思います。

たとえば、ユーザーが2013-5-1と2013-5-5の間に実行される5日間のサービスを購入している場合、discountとdiscount_exceptionテーブルをチェックして、2013-5に該当する例外がある割引を確認したいと思います。 -1および2013-5-5の場合、指定された日付範囲内に例外がない割引のみを表示します。SQLを分割して割引ごとにデータベースを個別に呼び出す代わりに、1つのselectステートメントでこれを行う方法はありますか?特に割引テーブルとdiscount_exceptionテーブルの間に1:Mの関係がある場合は、SQLに頭を悩ませるのに苦労しています。

私はこれに沿って何かを試みていました:

SELECT * FROM discount INNER JOIN `discount_exceptions` ON discount.id = discount_exceptions.discount_id AND (discount_exceptions.date_from NOT BETWEEN '2013-5-1' AND '2013-5-5' OR discount_exception.date_to NOT BETWEEN '2013-5-1' AND '2013-5-5');

しかし、これとこれの他のバリエーションは機能していないようです。私が間違っていることについて何か考えはありますか?

ありがとう!

4

3 に答える 3

1

これを試してみませんか:


select * 
   from discount
    where id not in (
        SELECT discount.id FROM discount
LEFT JOIN discount_exception ON discount.id = discount_exception.discount_id WHERE ('2013-5-1' between discount_exception.from_date and discount_exception.to_date ) OR ('2013-5-5' BETWEEN discount_exception.from_date and discount_exception.to_date ) OR (discount_exception.from_date between '2013-5-1' and '2013-5-5' ) OR (discount_exception.to_date between '2013-5-1' and '2013-5-5') ) )
おそらく、個別のIDを取得するために個別を追加する方が良いでしょう

于 2013-03-21T06:57:25.193 に答える
0

日付範囲「2013-03-01」から「2013-03-03」に適用されるすべての割引を検索するとします。最初に、この範囲に適用されるすべてのdiscount_exceptionsを検索します。

select e.*
from discount_exception e 
where e.from_date between '2013-03-02' and '2013-03-04'
or e.to_date between '2013-03-02' and '2013-03-04';

上記を割引テーブルと結合すると、この日付範囲に適用されるすべての割引例外の割引IDが得られます。重複するIDを取得しないように、Distinctキーワードが使用されます。これを「例外セット」と呼びましょう

select distinct d.id
from discount_exception e 
join discount d on d.id = e.discount_id
where e.from_date between '2013-03-02' and '2013-03-04'
or e.to_date between '2013-03-02' and '2013-03-04';

次に、割引テーブルの別の結合を実行して、日付範囲に適用可能なすべての割引を見つけることができます(つまり、上記の例外セットに含まれていない割引)。

select *
from discount
where id not in (
  select distinct d.id
  from discount_exception e 
  join discount d on d.id = e.discount_id
  where e.from_date between '2013-03-02' and '2013-03-04'
  or e.to_date between '2013-03-02' and '2013-03-04'
);
于 2013-03-22T04:24:51.207 に答える
0

交差点をチェックするには、どちらかの範囲の開始がもう一方の範囲内にあるかどうかを確認する必要があります。次に、サブクエリを作成して、一致するものを除外します。

set @start_date = CAST('2013-05-01' as date);
set @stop_date = CAST('2013-05-05' as date);

select *
from discounts
where id not in (select discount_id
                 from discount_exception
                 where from_date between @start_date and @stop_date or
                       @start_date between from_date and to_date)  
于 2013-03-22T05:04:48.237 に答える