Количество SQL в зависимости от определенных условий

#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 обычно они появляются в различных решениях ежедневно.