#sql #sql-server #tsql
#sql #sql-сервер #tsql
Вопрос:
У меня есть две таблицы.
У одного есть идентификатор пользователя и адрес электронной почты (таблица пользователей). У других есть информация о платежах (таблица платежей) из идентификатора пользователя в users.
users
-------- ------------
| Userid | Name |
-------- ------------
| 1 | Alex T |
| 2 | Jeremy T |
| 3 | Frederic A |
-------- ------------
payments
-------- ----------- ------------ ----------
| Userid | ValuePaid | PaidMonths | Refunded |
-------- ----------- ------------ ----------
| 1 | 1 | 12 | null |
| 1 | 20 | 12 | null |
| 1 | 20 | 12 | null |
| 1 | 20 | 1 | null |
| 2 | 1 | 1 | null |
| 2 | 20 | 12 | 1 |
| 2 | 20 | 12 | null |
| 2 | 20 | 1 | null |
| 3 | 1 | 12 | null |
| 3 | 20 | 1 | 1 |
| 3 | 20 | 1 | null |
-------- ----------- ------------ ----------
Я хочу подсчитать оплаченные месяцы с учетом следующих правил:
- Если оплаченное значение < 10 оплаченных месяцев должно быть = 0,23 (даже если в столбце отображается значение любого другого номера).
- Если возврат = 1, оплаченные месяцы должны быть = 0.
Исходя из этого, когда я объединяю обе таблицы по идентификатору пользователя и суммирую оплаченные месяцы, основанные на предыдущих правилах, я ожидаю увидеть результат:
-------- ------------ ------------
| userid | Name | paidMonths |
-------- ------------ ------------
| 1 | Alex T | 25.23 |
| 2 | Jeremy T | 13.23 |
| 3 | Frederic A | 1.23 |
-------- ------------ ------------
Можете ли вы помочь мне добиться этого самым элегантным способом? Следует ли использовать временную таблицу?
Комментарии:
1. MySQL <> SQL Server — пожалуйста, исправьте свои теги.
2. Что делать, если Valuepaid <10 и возврат = 1?
3. Этого не происходит, но оно будет равно 0. Ty stu
Ответ №1:
Ниже приведены желаемые результаты, используя apply
with case expression
для сопоставления ваших значений:
select u.UserID, u.Name, Sum(pm) PaidMonths
from users u join payments p on p.userid=u.userid
cross apply (values(
case
when valuepaid <10 then 0.23
when Refunded=1 then 0
else PaidMonths end
))x(pm)
group by u.UserID, u.Name
См. раздел Рабочая скрипка
Комментарии:
1. Это потрясающе! Это сработало. Я бы никогда туда не попал.
2. Вопрос, где вы изучаете продвинутые вещи, подобные этому? Я никогда раньше не видел, чтобы этот крест применял значения
3. @UcanDoIt — Cross apply — это синтаксис SQL Server для того, что называется a
lateral join
, это часть стандарта ANSI SQL и поддерживается почти всеми платформами RDBMS. Это часто поддается «чистому» решению, но не является «обязательным».4. как я могу узнать больше об этом необычном материале? есть какой-нибудь хороший продвинутый учебник по ms sql на YouTube или в любом другом месте, которое вы рекомендуете?
5. Мы учимся на практике — вы только что узнали что-то новое, задав вопрос о переполнении стека, продолжайте изучать новые вопросы и постарайтесь ответить на некоторые, если сможете, посмотрите на ответы других,
cross apply
иvalues
обычно они появляются в различных решениях ежедневно.