0

我有以下表格:

discount table:
id
name
description
amount

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

折扣例外表用于存储折扣不应提供给用户的日期范围,因此不应显示。请注意,折扣和折扣异常之间存在 1:M 关系。换句话说,一个折扣可以有很多例外。

现在,我编写 SQL 的方式是获取所有折扣,然后在数组中循环遍历它们,并查询 discount_exception 表以了解每个折扣是否在特定日期范围内。我更愿意修改 SQL,以便一个数据库调用可以获取所有不包含在指定日期范围内的异常日期的折扣。

例如,如果用户正在购买 2013-5-1 和 2013-5-5 之间运行的 5 天服务,我想检查 discount 和 discount_exception 表以找出哪些折扣在 2013-5 内有例外-1 和 2013-5-5,然后仅显示在指定日期范围内没有例外的折扣。有没有办法用一个 select 语句来做到这一点,而不是分解 SQL 来为每个折扣单独调用数据库?我很难理解 SQL,尤其是当 discount 表和 discount_exception 表之间存在 1:M 关系时。

我正在尝试这样的事情:

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') ) )
可能更好地添加 distinct 以获得不同的 ID

于 2013-03-21T06:57:25.193 回答
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 回答
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。让我们称之为“异常集”

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';

然后,您可以执行折扣表的另一个联接以查找适用于日期范围的所有折扣(即 id 不在上面设置的例外中的折扣)

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 回答