Mysql GROUP BY и Union на основе условия даты - PullRequest
0 голосов
/ 04 мая 2020

Вот мой запрос - он в основном работает, но я вижу, что он не работает при одном условии - объяснение после запроса:

$firstDay = '2020-03-01' ;
$lastDay = '2020-03-31' ;
SELECT * FROM clubEventsCal 
            WHERE ceFreq!=1
              AND (ceDate>='$firstDay' AND ceDate<='$lastDay') 
  UNION SELECT * FROM clubEventsCal 
            WHERE ceFreq=1
              AND (ceDate>='$firstDay' AND ceDate<='$lastDay') 
  GROUP BY ceStopDate ORDER BY ceID,ceDate ;

Первый выбор дает мне все записи событий между двумя датами. Второй выбор дает мне сгруппированные / обобщенные записи событий между двумя датами. Проблема, однако, в том, что значение ceDate охватывает дни в течение двух месяцев: IE: от 30.03.2020 до 02.04.2020. Когда я извлекаю записи за март, все в порядке - приведенный выше запрос извлекает запись 2020-03-30 (сгруппированную) в качестве первого экземпляра 4 дней / записей, что позволяет нам взимать плату за одно 4-дневное мероприятие. Но когда я вытаскиваю рекорды за апрель, он также будет вытаскивать 2020-04-01 в качестве новой сгруппированной записи события за последние два дня четырехдневного мероприятия и пытаться взимать с клиента плату за новое событие - хотя на самом деле эти два дня были уже является частью мартовского счета.

Как я могу написать запрос, чтобы, когда ceDate начинается в месяце X, но заканчивается в месяце Y, чтобы при извлечении записей за месяц Y он не пытался извлекать записи, которые фактически принадлежат событие, начавшееся в месяце X?

Примеры записи события будут выглядеть следующим образом:

rid | ceID  | ceActive   |   ceFreq   |  ceDate    | ceStopDate
------------------------------------------------
1    1108         1            3        2020-03-09 | 2020-03-09   
2    1111         1            2        2020-03-15 | 2020-03-15   
3    1112         1            2        2020-03-17 | 2020-03-17   
4    1117         1            1        2020-03-30 | 2020-04-02   
5    1117         1            1        2020-03-31 | 2020-04-02
6    1106         1            3        2020-03-21 | 2020-03-21   
7    1110         1            2        2020-03-05 | 2020-03-05   
8    1113         1            2        2020-03-24 | 2020-03-24   
9    1117         1            1        2020-04-01 | 2020-04-02
10   1117         1            1        2020-04-02 | 2020-04-02   

Приведенный выше запрос извлекает все записи, где ceFreq != 1, и извлекает одну запись для записей ceFreq = 1 (райды: 4 и 5). Что касается марта, нас не обязательно заботит, что ceID 1117 перейдет в апрель. Но когда мы получаем записи за апрель - нам нужно исключить rid 9 и 10, потому что событие (ceID = 1117) уже было учтено в марте.

1 Ответ

0 голосов
/ 05 мая 2020
SELECT * FROM clubEventsCal 
...
GROUP BY ceStopDate

Это гиббери sh.

MySQL (в зависимости от конфигурации) позволяет не задыхаться, но это семантически неверно и выделяется как антишаблон.

Есть некоторые крайние случаи, когда возвращаемые значения могут содержать важные данные, но они очень необычны. Попытка объяснить проблему с помощью кода, который не работает, возможно, не лучшая стратегия.

Глядя на ваш код, вполне возможно, что вам не нужно объединение, но в ваших примерах записей недостаточно информации для скажем, если бы это действительно дало ожидаемый результат (это будет значительно быстрее в зависимости от ваших индексов):

SELECT IF(cefreq=1, rid, null) AS consolidator
, ceid
, cefreq
, MIN(cedate), MAX(cedate)
, ceStopDate
FROM clubEventsCal 
WHERE cID=1001 
  AND ceActive!=2
  AND (ceDate>='$firstDay' AND ceDate<='$lastDay') 
GROUP BY IF(cefreq=1, rid, null)
, ceid
, cefreq
, ceStopDate
;

Я бы добавил ORDER BY, но я не знаю, откуда появился clId из. Кроме того, это даст разные результаты того, что, как я думаю, вы пытались достичь для любой записи, где cefreq имеет значение null (если вы действительно хотите их исключить, добавьте предикат в предложение WHERE).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...