如何在SQL中将事务数据与客户数据表联接并执行基于案例的操作

时间:2019-07-10 00:58:34

标签: sql sql-server join querying

我正在尝试在两个不同的表之间执行查询,并提出一个个案的方案,并列出了特定月份的通话记录列表。

这是我的桌子:

客户表:

+----+----------------+------------+
| id |      name      |   number   |
+----+----------------+------------+
|  1 | John Doe       | 8973221232 |
|  2 | American Dad   | 7165531212 |
|  3 | Michael Clean  | 8884731234 |
|  4 | Samuel Gatsby  | 9197543321 |
|  5 | Mike Chat      | 8794029819 |
+----+----------------+------------+

交易数据:

+----------+------------+------------+----------+---------------------+
| trans_id |  incoming  |  outgoing  | duration |      date_time      |
+----------+------------+------------+----------+---------------------+
|        1 | 8973221232 | 9197543321 |       64 | 2018-03-09 01:08:09 |
|        2 | 3729920490 | 7651113929 |      276 | 2018-07-20 05:53:10 |
|        3 | 8884731234 | 8973221232 |      382 | 2018-05-02 13:12:13 |
|        4 | 8973221232 | 9234759208 |      127 | 2018-07-07 15:32:30 |
|        5 | 7165531212 | 9197543321 |      852 | 2018-08-02 07:40:23 |
|        6 | 8884731234 | 9833823023 |      774 | 2018-07-03 14:27:52 |
|        7 | 8273820928 | 2374987349 |      120 | 2018-07-06 05:27:44 |
|        8 | 8973221232 | 9197543321 |       79 | 2018-07-30 12:51:55 |
|        9 | 7165531212 | 7651113929 |      392 | 2018-05-22 02:27:38 |
|       10 | 5423541524 | 7165531212 |      100 | 2018-07-21 22:12:20 |
|       11 | 9197543321 | 2983479820 |      377 | 2018-07-20 17:46:36 |
|       12 | 8973221232 | 7651113929 |      234 | 2018-07-09 03:32:53 |
|       13 | 7165531212 | 2309483932 |       88 | 2018-07-16 16:22:21 |
|       14 | 8973221232 | 8884731234 |       90 | 2018-09-03 13:10:00 |
|       15 | 3820838290 | 2093482348 |      238 | 2018-04-12 21:59:01 |
+----------+------------+------------+----------+---------------------+

我要完成什么?

我正在尝试为每个在2018年7月打电话的客户编制一份“费用”清单。费用基于:

1)如果客户接到一个电话(来电),则该电话的费用等于通话时间;

2)如果客户拨打了电话(去电),且通话时长为30分钟或更短,则通话费用为100。如果持续时间超过30天,则费用为100加5 *超出期限的持续时间。

如果客户在该月内没有拨打任何电话,则不应将其列入名单。

示例:

1)客户American Dad有3个拨入电话和1个拨出电话,但是7月份仅trans_id 10和13。他应该总共支付538:

  • 对于trans_id 10 = 450(前30秒为100 +其余为5 * 70)

  • 对于trans_id 13 = 88

2)客户Samuel Gatsby有1个拨入电话和3个拨出电话,但是7月份仅trans_id 8和11。他应该总共支付722:

  • 对于trans_id 8 = 345(前30秒为100 +其余为5 * 49)

  • 对于trans_id 11 = 377

仅考虑这两个示例,输出将是:

+----+----------------+------------+------------+
| id |      name      |   number   |  billable  |
+----+----------------+------------+------------+
|  2 | American Dad   | 7165531212 |        538 |
|  4 | Samuel Gatsby  | 9197543321 |        722 |
+----+----------------+------------+------------+

注意:Mike Chat不应该出现在列表中,因为他在该特定月份没有拨打或接听任何电话。

到目前为止,我尝试了什么?

我一直在玩猫和老鼠,我正在使用数字作为uniqueID,已经尝试了完全外部联接并组合了传入或传出不为null的情况,然后按大小写应用规则,尝试做一个左加入和申请案例,但是我盘旋而已,无法到达最终清单。每当我收到或传出邮件时,我要么无法申请该案件,要么无法一起处理这两个案件。非常感谢您的帮助!

select customer_name.name, customer_name.number, bill = (CASE
                                                         WHEN customer_name.number = transaction_data.incoming then 'sum bill'
                                                         else 'multiply and add'
                                                         end)
from customer_name
left join transaction_data on customer_name.number = transaction_data.incoming or customer_name.name = transaction_data.outgoing
where strftime('%Y-%m', transaction_data.date_time) = '2018-07'

注意:我正在使用sqlite进行在线试用,但是数据库位于SQL Server 2012上,因此我知道可以更轻松地使用日期格式,但是我希望保持接近尽可能使用T-SQL。

还尝试创建一个案例来确定它是呼入还是呼出,但是即使trans_id 10是呼出,我也只能因此进入:

select name, number, duration, case 
    when customer_name.number = transaction_data.incoming then 'incoming'
    when customer_name.number = transaction_data.outgoing then 'outgoing'
END direction
from customer_name
left join transaction_data on customer_name.number = transaction_data.incoming or customer_name.name = transaction_data.outgoing
where strftime('%Y-%m', transaction_data.date_time) = '2018-07'

1 个答案:

答案 0 :(得分:1)

尝试一下:

SELECT
  c."name", c.number,
  SUM(CASE c.number
        WHEN t.incoming THEN t.duration
        ELSE IIF(t.duration - 30 < 0, 0, t.duration - 30) * 5 + 100
      END) AS billable
FROM Customer AS c INNER JOIN [Transaction] AS t
  ON c.number IN(t.incoming, t.outgoing)
WHERE t.date_time >= '20180701' AND t.date_time < '20180801'
GROUP BY c."name", c.number

输出:

|     name      |   number   | billable |
+---------------+------------+----------+
| John Doe      | 8973221232 |      440 |
| American Dad  | 7165531212 |      538 |
| Michael Clean | 8884731234 |      774 |
| Samuel Gatsby | 9197543321 |      722 |

使用SQL Fiddle在线进行测试。