У меня есть несколько проблем с тем, что, вероятно, является достаточно простым SQL-выражением - к сожалению, мои навыки не идут настолько далеко, насколько это возможно, и я не могу обдумать это!
Я имею, например, следующие таблицы:
В бронировании может быть много заказов для одного клиента, они связаны через "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
Я быстро просмотрел представления, но это используется в дизайнере отчетов, который, как представляется, не поддерживает представления (или, по крайней мере, не во время разработки). Можно ли получить то, что мне нужно, без использования представлений?
Спасибо, Даниэль.
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.
Использование:
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')
В MySQL NOT IN
и LEFT JOIN/IS NULL
быстрее, чем NOT EXISTS
. Для дополнительную информацию см. В этой ссылке для более подробной информации.
Так как я много не работаю с 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>