Я полностью согласен с Риком по поводу очистки схемы
Если я правильно вас прочитал, в настоящее время ваша таблица customer
фактически просто добавляет столбцы email
и name
к вашему orders
таблица
Q1
Если вы хотите, чтобы в течение недели с сегодняшней даты поля идентификатора не могли быть пустыми
SELECT ou.*
FROM orders ou /** orders unpaid */
JOIN customer cu /** customer unpaid */
ON cu.id = ou.customer_id
WHERE ou.payment_status = 'unpaid'
AND NOT EXISTS (
SELECT 1
FROM orders op /** orders paid */
JOIN customer cp /** customer paid */
ON cp.id = op.customer_id
WHERE op.payment_status = 'paid'
AND op.created_on > CURDATE() - INTERVAL 1 WEEK /** or >= if required */
AND cp.email = cu.email
)
NB Поскольку с момента оплаченных заказов в ваших примерах прошло больше недели, вам придется отрегулировать временное условие, чтобы увидеть те же результаты
Q2
Те же предположения, что и в первом квартале, плюс предположение о том, что product_id
может появляться только один раз за заказ
SELECT ou.*
FROM orders ou /** orders unpaid */
JOIN customer cu /** customer unpaid */
ON cu.id = ou.customer_id
JOIN (
SELECT GROUP_CONCAT(oudc.id) orders_csv
FROM (
SELECT oui.id,
cui.email,
GROUP_CONCAT(oiui.product_id ORDER BY oiui.product_id) products,
GROUP_CONCAT(oiui.quantity ORDER BY oiui.product_id) quantity
FROM orders oui /** orders unpaid internal */
JOIN customer cui /** customer unpaid internal */
ON cui.id = oui.customer_id
JOIN order_items oiui /** order items unpaid internal */
ON oiui.order_id = oui.id
WHERE oui.payment_status = 'unpaid'
GROUP BY oui.id,
cui.email
) oudc /** orders unpaid dupe check */
GROUP BY oudc.email,
oudc.products,
oudc.quantity
HAVING COUNT(*) = 2 /** or >=2 if required */
) oud /** orders unpaid dupes */
ON FIND_IN_SET(ou.id, oud.orders_csv) > 0
WHERE ou.payment_status = 'unpaid'
AND NOT EXISTS (
SELECT 1
FROM orders op /** orders paid */
JOIN customer cp /** customer paid */
ON cp.id = op.customer_id
WHERE op.payment_status = 'paid'
AND op.created_on > CURDATE() - INTERVAL 1 WEEK /** or >= if required */
AND cp.email = cu.email
)
NB Поскольку с момента оплаты оплаченных заказов прошло более неделиВ ваших примерах вам нужно будет скорректировать временное условие, чтобы увидеть те же результаты
Этот запрос проверен только приблизительно и, вероятно, очень медленный.Я предлагаю вам выполнить каждый вложенный запрос выбора по отдельности (начиная с самого глубокого), чтобы увидеть, что происходит.По сути, он объединяет заказы в 1 строку каждый, затем объединяет дубликаты заказов с одним и тем же адресом электронной почты в 1 строку каждый, а затем проверяет наличие заказов в этой строке, используя логику, аналогичную Q1
Если вы можете иметь одинаковые product_id
более одного раза за заказ, вы можете нормализовать с помощью дополнительной вложенной группировки, выбранной в моем orders unpaid dupe check
подзапросе
SQLfiddle
У меня также создал SQLfiddle , чтобы продемонстрировать эти 2 запроса в действии на данных вашего примера.Однако я настроил даты примеров заказов, чтобы они зависели от текущей даты