使用与嵌套选择和临时表

时间:2015-11-11 19:04:57

标签: php mysql iteration union

这是@amdixon前几天this thread给出的优秀答案的后续问题。

快速摘要:我有这个MySql表(简化):

tbl_cards
ID  FROM        TO
--------------------------
1  2015-10-01  2015-10-08
2  2015-10-06  2015-10-12
3  2015-10-06  2015-10-15
4  ...

我需要一个SELECT来检查每个日期之间的日期。 2015-10-01和2015-12-31并返回ID(或任意数量)ID重叠的日期。有些日期没有任何记录,而其他日期可能有很多。

@amdixon为我提供了这个答案,这正是我所需要的(请注意,还有一个mySql视图叫做'数字'参与。看看上面的帖子)

select @index := @index + 1 as `Index`, `Date`
from
(
select date_format(calendar.dy, '%Y-%m-%d') as `Date`
from
(
select date_add(date('2015-10-01'), interval (a2.digit * 100) + (a1.digit * 10) + a0.digit day) as dy
from digits a2
cross join digits a1
cross join digits a0
where date_add('2015-10-01', interval (a2.digit * 100) + (a1.digit * 10) + a0.digit day) <= date('2015-12-31')
order by date_add('2015-10-01', interval (a2.digit * 100) + (a1.digit * 10) + a0.digit day)
) calendar
inner join tbl_cards t
on calendar.dy between t.`from` and t.`to`
group by calendar.dy
having count(calendar.dy) = 3
) dts
cross join ( select @index := -1 ) params
;

对于我的后续问题,可能有必要提供一些进一步的细节。 tbl_cards表用于存储可以跨越一到十个日期的所有预订。因此,fromto字段。

现在,我的一位客户要求我为此制作一个购物车,这意味着每个用户可以在一次交易中进行多次预订。我希望通过创建一个tbl_shoppingcart来预订,其中预订会暂时存储30分钟左右,直到用户完成并完成付款为止。

然而,这使得上面的优秀查询已经过时,因为calendar现在需要同时与tbl_cardstbl_shoppingcart进行比较,并确保已确认的预订总数+购物车任何指定日期的预订量不超过3(或我的客户定义的任意数字)。

我确定会涉及UNION,但我真的不知道放在哪里,因为HAVING COUNT子句应该跨越两个表。

这里是@amdixon提供的sqlfiddle

1 个答案:

答案 0 :(得分:0)

在我的头部扭转了大约24小时之后,我能够在Stack Overflow上从类似的帖子中获得正确的查询(但是不那么复杂的查询):

select @index := @index + 1 as `Index`, `Date`
from
(
  select date_format(calendar.dy, '%Y-%m-%d') as `Date`
  from
  (
    select date_add(date('2015-10-01'), interval (a2.digit * 100) + (a1.digit * 10) + a0.digit day) as dy
    from digits a2
    cross join digits a1
    cross join digits a0
    where date_add('2015-10-01', interval (a2.digit * 100) + (a1.digit * 10) + a0.digit day) <= date('2015-12-31')
    order by date_add('2015-10-01', interval (a2.digit * 100) + (a1.digit * 10) + a0.digit day)
  ) calendar
  inner join
  (
    SELECT `ID`, `from`, `to` FROM `tbl_cards`
    UNION
    SELECT `ID`, `from`, `to` FROM `tbl_shoppingcart`
  ) t
  on calendar.dy between t.`from` and t.`to`
  group by calendar.dy
  having count(calendar.dy) = 3
) dts
cross join ( select @index := -1 ) params
;

显然,我对衍生表和子查询不够了解,否则这将是一个简单的定制。好像我今天也学到了新东西:)