SQL запрос с выборкой из 3-х таблиц - как сделать правильно и красиво?

Мемори
На сайте с 11.11.2012
Offline
105
827

Приветствую!

Коллеги, подскажите как правильно, в правильном стиле составлять запросы к 3 таблицам

когда сквозного user_id нет ? Как учат в ВУЗ-ах такие запросы составлять?

Users1 - таблица с user_id email дата регистрации

Transaction - таблица с user_id Сумма

Webinar - таблица с email

Задача - получить список email с датой регистрации в Users1 позже 1.04.2016 с суммой всех транзакций и состоящих в Webinar.

Я по дилетански 1-запрос - суммы тразакций по user_id из Transactions (один user_id может иметь несколько транзакций)

2-запрос - объединили все данные в одну таблицу или view или в терминах Access - именной запрос

3-запрос из этой общей таблицы выбираем все имейл которые не в списке старых и считаем SUM по транзакциям

поянения почему NOT IN, а не IN? некоторые email могут иметь несколько дат регистраций до и после нужной даты

и если будем проверять IN то попадут email которые и до и после. а надо только после)

Что мне самому не нравится и наверное не красиво с точки зрения профи - объединение в одну таблицу

и вообще 3 запроса, нельзя ли это в один запрос как-то сделать?

Все 3 таблицы в SQL/Access2007 https://yadi.sk/d/KGa391Ek3SgHye

Запрос 1 (tempQ1)

SELECT Transactions.user_id, SUM(Transactions.price) AS price

FROM Transactions

GROUP BY Transactions.user_id;

ЗАПРОС 2 (tempQ2)

SELECT tempQ1.user_id, tempQ1.price, Users1.email, Users1.user_id AS id, Users1.date_registration AS RegDate

FROM tempQ1, Users1

WHERE tempQ1.user_id=Users1.user_id

AND email IN

(

SELECT email FROM Webinar

)

AND

(

(((Users1.[date_registration])>#4/1/2015#))

);

ЗАПРОС 3 (Запрос1)

SELECT email, SUM(price) AS Summa, MIN(RegDate) AS Min_Reg_Date, MAX(RegDate) AS Max_Reg_Date, COUNT(RegDate) AS Quantity

FROM tempQ2

WHERE email NOT IN

(

SELECT email FROM Users1 WHERE (((Users1.[date_registration])<#4/1/2016#))

)

GROUP BY email;

Users1

user_id email date_registration

----------------------------------------------------------------

456481 desbo@ya.ru 22.04.2016 15:00:00

46545 s_k76@bk.ru 21.04.2016 15:00:00

44545 s_k76@bk.ru 02.05.2016 15:00:00

456451 s_k76@bk.ru 08.06.2016 15:00:00

123213 sekretshop@mail.ru 02.06.2016 15:00:00

456281 tte-84@mail.ru 22.03.2016 15:00:00

35656 waitingforward@mail.ru 02.03.2016 15:00:00

35657 waitingforward@mail.ru 02.05.2016 15:00:00

Transaction

user_id price

--------------------------------

43243 1000

456281 1000

456451 1000

46545 1000

44545 1000

43343 1000

43343 1000

43343 1000

43343 1000

43343 1000

35656 1000

35657 1000

Webinar

email

---------------------

9169399@mail.ru

academi@academy-trading.com

ixdir@dimaxweb.ru

liverpool64@bk.ru

n3p@bk.ru

np1968@mail.ru

reklamagrad@mail.ru

s_k76@bk.ru

serdepar@yandex.ru

waitingforward@mail.ru

Оптимизайка
На сайте с 11.03.2012
Offline
396
#1
Мемори:
получить список email с датой регистрации в Users1 позже 1.04.2016 с суммой всех транзакций и состоящих в Webinar

select Users1.email, sum(Transaction.price)

from Users1

join Transaction on (Transaction.user_id = Users1.user_id)

join Webinar on (Webinar.email = Users1.email)

where Users1.date_registration > '01.04.2016'

⭐ BotGuard (https://botguard.net) ⭐ — защита вашего сайта от вредоносных ботов, воровства контента, клонирования, спама и хакерских атак!
ДП
На сайте с 23.11.2009
Offline
203
#2

group by Users1.user_id

еще наверно

Мемори
На сайте с 11.11.2012
Offline
105
#3

Окончательный вариант запроса

SELECT (Users1.), COUNT(Users1.[user_id]) AS User_id_COUNT, SUM(Transactions.[price]) AS SUMMA, MIN(Users1.date_registration) AS RegDate_MIN
FROM ((Users1 INNER JOIN Transactions ON (Users1.[user_id] = Transactions.[user_id]) )
INNER JOIN Webinar ON (Users1. = Webinar.) )
WHERE Users1.email NOT IN ( SELECT email FROM Users1 WHERE (((Users1.[date_registration])<#4/1/2016#)) )
GROUP BY Users1.email

Но как-то не нравится что два раза JOIN и все три таблицы сливаются в одну, что будет в случае если таблицы будут весьма большие?
Можно ли (и нужно ли?) сделать без JOIN ?

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий