包含复杂的查询date_format和之间

时间:2017-07-18 04:53:20

标签: cakephp associations conditional-statements cakephp-3.0

  

代码更新2017/07/20

我遵循@Arcesilas(here)的建议,使用MySQL的date_format

我通过合并start_monthstart_day (2017-01-16 = 0116)来升级我的数据结构

new data structuree

[...]
->contain([
    'Bookings', 
    'Amenities',
    'Periodicities' =>  function ($q) use ($check_in, $check_out) {
        $start = $q->func()->date_format([
            'Periodicities.start' => $check_in->format('Ymd'),
            "'%m%d'" => 'literal'
        ]);

        $end = $q->func()->date_format([
            'Periodicities.end' => $check_out->format('Ymd'),
            "'%m%d'" => 'literal'
        ]);

       return $q
            ->where(function ($exp) use ($start) {
                $exp->between($start, 'Periodicities.start', 'Periodicities.end');
                return $exp;
            })
            ->orWhere(function ($exp) use ($end) {
                $exp->between($end, 'Periodicities.start', 'Periodicities.end');
                return $exp;
            });
    }

])
[...]

Cakephp SQL日志

SELECT 
      PeriodicitiesRooms.id AS `Periodicities_CJoin__id`, 
      PeriodicitiesRooms.periodicity_id AS `Periodicities_CJoin__periodicity_id`, 
      PeriodicitiesRooms.room_id AS `Periodicities_CJoin__room_id`, 
      PeriodicitiesRooms.price AS `Periodicities_CJoin__price`, 
      Periodicities.id AS `Periodicities__id`, 
      Periodicities.name AS `Periodicities__name`, 
      Periodicities.start AS `Periodicities__start`, 
      Periodicities.end AS `Periodicities__end`, 
      Periodicities.price AS `Periodicities__price`, 
      Periodicities.modified AS `Periodicities__modified` 
    FROM 
      periodicities Periodicities 
      INNER JOIN periodicities_rooms PeriodicitiesRooms ON Periodicities.id = (
        PeriodicitiesRooms.periodicity_id
      ) 
    WHERE 
  (
    date_format('20170726', '%m%d') BETWEEN 'Periodicities.start' 
    AND 'Periodicities.end' 
    OR (
      PeriodicitiesRooms.room_id in ('1', '2', '3') 
      AND date_format('20170720', '%m%d') BETWEEN 'Periodicities.start' 
      AND 'Periodicities.end'
    )
  )

这不会给我任何结果,因为CakePHP的ORM将撇号(')添加到BETWEEN' Periodicities.start 'AND' Periodicities.end'的末尾

如果在我的数据库中我粘贴CakePHP查询而没有撇号(')它可以工作。您是否知道在查询结束时要做出哪些更改,以便它看起来像这样:BETWEEN 'Periodicities.start' AND 'Periodicities.end'BETWEEN Periodicities.start AND Periodicities.end

'SELECT * FROM periodicities WHERE date_format(' . $check_in->format('Ymd') . ', '%m%d') BETWEEN start AND end'

2 个答案:

答案 0 :(得分:1)

修改

从你的评论中我发现你不想存储多年,因为这一年并不相关。

在这种情况下,您仍然可以将所有日期存储为特定年份,然后将该年份硬编码到查询中。我已将查询修改为使用2000年。

<强> ORIGINAL

对话我不清楚,但我会尝试回答我相信你问的问题。

您似乎想知道如何在结帐时间和结帐时间之间的周期之间找到周期。

您似乎也想知道存储日期的最佳方式。

  • 只需将日期存储为日期。不需要复杂化
  • Between也过于复杂。

这将做你需要做的事情而不会混淆。

[...]
->contain([
    'Bookings', 
    'Amenities',
    'Periodicities' =>  function ($q) use ($check_in, $check_out) {
        $q->where([
            'Periodicities.start >' => $check_in->format('2000-m-d'),
            'Periodicities.end <' => $check_in->format('2000-m-d')
        ]);
        $q->orWhere([
            'Periodicities.start >' => $check_out->format('2000-m-d'),
            'Periodicities.end <' => $check_out->format('2000-m-d')
        ]);

        return $q;
    }

])
[...]

答案 1 :(得分:1)

我用这个查询解决了我的问题:

->contain([
    'Bookings', 
    'Amenities',
    'Periodicities' =>  function ($q) use ($check_in, $check_out) {
        $q->where(function ($exp) use ($check_in, $check_out) {
            $exp->gte('Periodicities.start', $check_in->format('md'));
            $exp->lte('Periodicities.end', $check_out->format('md'));
        });
        return $q;
    }
])

我一直使用monthday md格式存储在数据库日期中 例:0901&lt; 1030 9月1日&lt; 10月30日