MySQL - Выбор «Все, кто забронировал номер в прошлом январе, но не забронировал номер в этом январе»

0

У меня есть несколько проблем с тем, что, вероятно, является достаточно простым SQL-выражением - к сожалению, мои навыки не идут настолько далеко, насколько это возможно, и я не могу обдумать это!

Я имею, например, следующие таблицы:

  • booking_record
  • клиент

В бронировании может быть много заказов для одного клиента, они связаны через "labelno".

Я хотел бы выбрать клиентов, которые забронировали последний, но не забронировали это. То есть Этот клиент забронировал этот месяц в прошлом году, но не забронировал в этом году.

Я только добрался до любой ситуации, например:

Select client_.title, 
       client_.initial, 
       client_.surname, 
       client_.labelno,
       client_.email, 
       booking_record_.bookingdate
From booking_record booking_record_ 
Inner Join client client_ On booking_record_.labelno = client_.labelno
Where client_.email Not Like '' 
  And Date_Format(booking_record_.bookingdate, '%m') = ?Param1 
  And Date_Format(booking_record_.bookingdate, '%Y') = Year(AddDate(Now(), Interval -1 Year))
Group By client_.labelno

Я быстро просмотрел представления, но это используется в дизайнере отчетов, который, как представляется, не поддерживает представления (или, по крайней мере, не во время разработки). Можно ли получить то, что мне нужно, без использования представлений?

Спасибо, Даниэль.

Теги:

3 ответа

0
Лучший ответ
    Select c.title, 
           c.initial, 
           c.surname, 
           c.labelno,
           c.email
    from
        client c
    where exists (select * from booking_record where labelno=c.labelno
        and bookingdate between @start1 and @end1)
    and not exists (select * from booking_record where labelno=c.labelno
        and bookingdate between @start2 and @end2)

Это принимает start1 и end1 как даты для окна бронирования в прошлом году, а start2 и end2 для этого года, и должен возвращать список всех клиентов в первом списке, но не второй. Извините, если код переменной не подходит для вас, это время с тех пор, как я сделал MySQL, но все остальное должно быть в порядке - вы хотите, чтобы двойная проверка EXISTS в вашем предложении where.

1

Использование:

SELECT c.title,
       c.initial,
       c.surname,
       c.labelno,
       c.email,
       br.booking date
  FROM CLIENT c
  JOIN BOOKING_RECORD br ON br.labelno = c.labelno
                        AND br.bookingdate BETWEEN STR_TO_DATE(?Param1, '%Y-%m-%d')
                                               AND STR_TO_DATE(?Param2, '%Y-%m-%d')
 WHERE c.label_no NOT IN (SELECT t.label_no
                            FROM BOOKING_RECORD t
                           WHERE br.bookingdate BETWEEN STR_TO_DATE(?Param3, '%Y-%m-%d')
                                                    AND STR_TO_DATE(?Param4, '%Y-%m-%d')
  • Param1 и 2 представляют даты в прошлом, которые вы хотите проверить на наличие IE Jan в прошлом году.
  • Param3 и 4 представляют даты, которые вы хотите проверить, чтобы клиент не имел.
  • Использование функций в столбцах для оценки означает, что, если для столбца существует индекс, индекс не может использоваться.

Протест:


В MySQL NOT IN и LEFT JOIN/IS NULL быстрее, чем NOT EXISTS. Для дополнительную информацию см. В этой ссылке для более подробной информации.

Справка:


  • STR_TO_DATE
  • DATE_FORMAT: список поддерживаемых масок даты для использования в STR_TO_DATE
  • 0
    Спрашивающий спросил одну вещь, но его пример показывает что-то немного другое. В этом коде (как и в его примере) будет показан список всех заказов клиентов за период, а не всех клиентов - следовательно, клиент, который бронировал более одного раза, будет отображаться более одного раза. Если вы не хотите этого, вам нужно избегать объединения.
0

Так как я много не работаю с mySQL и не знаю всех функций даты, я просто использовал описания для дат ниже. Попробуйте написать запрос таким образом вместо использования функций в столбцах таблицы, поскольку это может исключить использование индексов.

SELECT
     C.title,
     C.initial,
     C.surname,
     C.labelno,
     C.email,
     BR.bookingdate
FROM
     Booking_Record BR1
INNER JOIN Client C ON
     C.labelno = BR.labelno AND
     C.email NOT LIKE ''
WHERE
     BR1.bookingdate >= <jan. 1st last year> AND
     BR1.bookingdate < <feb. 1st last year> AND
     NOT EXISTS
     (
          SELECT
               *
          FROM
               Booking_Record BR2
          WHERE
               BR2.labelno = BR1.labelno AND
               BR2.bookingdate >= <jan. 1st this year> AND
               BR2.bookingdate < <feb. 1st this year>

Ещё вопросы

Сообщество Overcoder
Наверх
Меню