每月交易(一)

Table: Transactions

+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| country | varchar |
| state | enum |
| amount | int |
| trans_date | date |
+---------------+---------+
id 是这个表的主键。
该表包含有关传入事务的信息。
state 列类型为 “[”批准“,”拒绝“] 之一。

问题:编写一个 sql 查询来查找每个月和每个国家/地区的事务数及其总金额、已批准的事务数及其总金额。

查询结果格式如下所示:

Transactions table:
+------+---------+----------+--------+------------+
| id | country | state | amount | trans_date |
+------+---------+----------+--------+------------+
| 121 | US | approved | 1000 | 2018-12-18 |
| 122 | US | declined | 2000 | 2018-12-19 |
| 123 | US | approved | 2000 | 2019-01-01 |
| 124 | DE | approved | 2000 | 2019-01-07 |
+------+---------+----------+--------+------------+

Result table:
+----------+---------+-------------+----------------+--------------------+-----------------------+
| month | country | trans_count | approved_count | trans_total_amount | approved_total_amount |
+----------+---------+-------------+----------------+--------------------+-----------------------+
| 2018-12 | US | 2 | 1 | 3000 | 1000 |
| 2019-01 | US | 1 | 1 | 2000 | 2000 |
| 2019-01 | DE | 1 | 1 | 2000 | 2000 |
+----------+---------+-------------+----------------+--------------------+-----------------------+

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/monthly-transactions-i
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

代码一:

select date_format(T.trans_date,'%Y-%m') as month, T.country,
count(*) as trans_total_count,
sum(T.state='approved') as approved_count, # 注意,这里使用sum()函数,不能使用count()函数
sum(amount) as trans_total_amount,
sum((T.state='approved')*amount) as approved_total_amount from Transactions4 T group by month(T.trans_date),T.country
order by month , country desc;

代码二: 和代码以相比,select 语句后有点不同,使用if 判断

select date_format(T.trans_date,'%Y-%m') as month, T.country,
count(*) as trans_total_count,
sum(if(T.state='approved',1,0)) as approved_count, # 注意,这里使用sum()函数,不能使用count()函数
sum(amount) as trans_total_amount,
sum(if(T.state='approved',amount,0)) as approved_total_amount from Transactions4 T group by month(T.trans_date),T.country
order by month , country desc;

每月交易(二)

Transactions 记录表

+----------------+---------+
| Column Name | Type |
+----------------+---------+
| id | int |
| country | varchar |
| state | enum |
| amount | int |
| trans_date | date |
+----------------+---------+
id 是这个表的主键。
该表包含有关传入事务的信息。
状态列是类型为 [approved(已批准)、declined(已拒绝)] 的枚举。

Chargebacks 表

+----------------+---------+
| Column Name | Type |
+----------------+---------+
| trans_id | int |
| charge_date | date |      注:这个题目给的是charge_date,但它定义表检查答案的时候定义的是trans_date,所以代码中chargebacks表中这一列也定义成了trans_date
+----------------+---------+
退单包含有关放置在事务表中的某些事务的传入退单的基本信息。
trans_id 是 transactions 表的 id 列的外键。
每项退单都对应于之前进行的交易,即使未经批准。

问题:编写一个 SQL 查询,以查找每个月和每个国家/地区的已批准交易的数量及其总金额、退单的数量及其总金额。

注意:在您的查询中,给定月份和国家,忽略所有为零的行。

查询结果格式如下所示:

Transactions 表:
+------+---------+----------+--------+------------+
| id | country | state | amount | trans_date |
+------+---------+----------+--------+------------+
| 101 | US | approved | 1000 | 2019-05-18 |
| 102 | US | declined | 2000 | 2019-05-19 |
| 103 | US | approved | 3000 | 2019-06-10 |
| 104 | US | approved | 4000 | 2019-06-13 |
| 105 | US | approved | 5000 | 2019-06-15 |
+------+---------+----------+--------+------------+

Chargebacks 表:
+------------+------------+
| trans_id | trans_date |
+------------+------------+
| 102 | 2019-05-29 |
| 101 | 2019-06-30 |
| 105 | 2019-09-18 |
+------------+------------+

Result 表:
+----------+---------+----------------+-----------------+-------------------+--------------------+
| month | country | approved_count | approved_amount | chargeback_count | chargeback_amount |
+----------+---------+----------------+-----------------+-------------------+--------------------+
| 2019-05 | US | 1 | 1000 | 1 | 2000 |
| 2019-06 | US | 3 | 12000 | 1 | 1000 |
| 2019-09 | US | 0 | 0 | 1 | 5000 |
+----------+---------+----------------+-----------------+-------------------+--------------------+

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/monthly-transactions-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

个人思路:

select distinct  a.month, a.country,ifnull(b.approved_count,0) as approved_count,    # 加了distinct,是因为最终结果中可能会有重复值
ifnull(b.approved_amount,0) as approved_amount, ifnull(c.chargeback_count,0) as chargeback_count,
ifnull(c.chargeback_amount,0) as chargeback_amount from
(select date_format(T.trans_date,'%Y-%m')as month, T.country as country from Transactions as T # 如这张表中有两个相同的月份和国家,结果中就会产生重复值,在这里加distinct没有太大用途,因为和下面一张表Union时,还会产生重复值,所以是在最终结果中加入distinct关键字
group by month(T.trans_date),T.country
union all
select date_format(C.trans_date,'%Y-%m')as month , T.country as country
from Chargebacks as C join Transactions as T on C.trans_id=T.id
group by month(C.trans_date),T.country) a left join (select date_format(T.trans_date,'%Y-%m') as month ,T.country, count(T.id) as approved_count, sum(T.amount) as approved_amount
from Transactions as T
where T.state='approved'
group by month(T.trans_date) ,T.country) b on a.month=b.month and a.country=b.country left join (select date_format(C.trans_date,'%Y-%m') as month,T.country, count(T.id) as chargeback_count ,sum(T.amount) as chargeback_amount
from Transactions as T join Chargebacks as C on T.id=C.trans_id
group by month(C.trans_date),T.country) c on a.month=c.month and a.country=c.country where isnull(b.approved_count)+isnull(c.chargeback_count)<2 # 判断非零行,当count为0时,对应的amount一定也是0,所以当approved_count和chargeback_count都为0时,使用isnull()函数判断后,这两者相加结果为2,小于2说明,其中一个count有值
order by a.month;

代码分析:

a表:这张表中的月份和country是最全的,是在这张表的基础上进行left join的

PS:group by 字段后面有2个字段,select语句查询2个字段,不要忘记查询country;  因为b表和c表中的country可能完全都不相同,此时使用left join不能得到正确的结果,所以select语句查询时包含country字段,因此,group by字段后面也要添加country分组

select date_format(T.trans_date,'%Y-%m')as month, T.country as country from  Transactions as T
group by month(T.trans_date),T.country
union all
select date_format(C.trans_date,'%Y-%m')as month , T.country as country
from Chargebacks as C join Transactions as T on C.trans_id=T.id
group by month(C.trans_date),T.country

运行结果:

b表:

select date_format(T.trans_date,'%Y-%m') as month ,T.country, count(T.id) as approved_count, sum(T.amount)  as approved_amount
from Transactions as T
where T.state='approved'
group by month(T.trans_date) ,T.country

运行结果:

c表:

select date_format(C.trans_date,'%Y-%m') as month,T.country, count(T.id) as chargeback_count ,sum(T.amount) as chargeback_amount
from Transactions as T join Chargebacks as C on T.id=C.trans_id
group by month(C.trans_date),T.country

运行结果:

万能网友:

select date_format(a.trans_date,"%Y-%m") month,
a.country,
sum(a.sta="approved") approved_count, #这几句只能使用sum()函数,不能使用count()函数
sum((a.sta="approved")*a.amount) approved_amount,
sum(a.sta="backs") chargeback_count,
sum((a.sta="backs")*a.amount) chargeback_amount
from
(select *,"approved" as sta # 添加了一列, 列名sta
from Transactions
where state="approved"
union all
select c.trans_id,t.country,t.state,t.amount,c.trans_date,"backs" as sta #也添加了一列,要注意:列名要和前面添加的相同,都是sta
from Chargebacks c
left join transactions t
on t.id=c.trans_id
) as a
group by date_format(a.trans_date,"%Y-%m"),a.country
having sum(a.sta="approved")+sum(a.sta="backs")<>0
order by date_format(a.trans_date,"%Y-%m");

代码分析:

中间过程表的格式:

select *,"approved" as sta   # 添加了一列, 列名sta
from Transactions
where state="approved"
union all
select c.trans_id,t.country,t.state,t.amount,c.trans_date,"backs" as sta #也添加了一列,要注意:列名要和前面添加的相同,都是sta
from Chargebacks c left join transactions t on t.id=c.trans_id

运行结果:

测试用表:

第一张:

"Transactions":

[[100,"CB","declined",4000,"2019-02-04"]

,[101,"BB","approved",7000,"2019-02-17"]

,[102,"CA","declined",6000,"2019-02-26"]

,[103,"AA","declined",7000,"2019-04-01"]]

"Chargebacks":

[[100,"2019-03-29"],

[102,"2019-02-28"]

,[103,"2019-05-09"]]}}

第二张:这一张是说明最后结果会有重复值,所以在最终结果处加distinct关键字

"Transactions"

:[[101,"US","approved",1000,"2019-05-18"]

,[102,"US","declined",2000,"2019-05-19"],

[103,"US","approved",3000,"2019-06-10"],

[104,"US","declined",4000,"2019-06-13"]

,[105,"US","approved",5000,"2019-06-15"]],

"Chargebacks"

:[[102,"2019-05-29"],

[101,"2019-06-30"],

[105,"2019-09-18"]]}}

第三张表: b表和c表中,使用group by子句时,不要忘了country字段也要分组

"Transactions":

[[100,"BB","declined",2000,"2019-02-25"],

[101,"CA","declined",4000,"2019-02-22"],

[102,"BA","declined",2000,"2019-03-17"]

,[103,"AC","declined",6000,"2019-02-12"]

,[104,"AA","approved",3000,"2019-02-20"]

[105,"AB","declined",7000,"2019-03-22"]],

"Chargebacks

:[[100,"2019-04-26"]

[101,"2019-03-09"],

[103,"2019-03-07"],

[105,"2019-06-12"]]}}

第四张表:

"Transactions"

:[[100,"CB","approved",3000,"2019-04-11"]

,[101,"CC","declined",8000,"2019-04-05"],

[102,"BC","approved",2000,"2019-04-16"],

[103,"BC","approved",6000,"2019-02-18"],

[104,"AA","declined",7000,"2019-04-23"]

,[105,"CA","declined",1000,"2019-03-12"],

[106,"AA","declined",3000,"2019-03-24"],

[107,"CB","declined",2000,"2019-03-24"]],"

Chargebacks"

:[[100,"2019-07-05"]

,[101,"2019-04-15"],

[102,"2019-07-09"],

[103,"2019-03-06"]

,[104,"2019-05-08"]

,[105,"2019-05-12"]

,[106,"2019-04-10"]

,[107,"2019-07-01"]

leetcode 数据库练习 - 1205 每月交易I和II的更多相关文章

  1. Leetcode 137. 只出现一次的数字 II - 题解

    Leetcode 137. 只出现一次的数字 II - 题解 137. Single Number II 在线提交: https://leetcode.com/problems/single-numb ...

  2. [Leetcode 90]求含有重复数的子集 Subset II

    [题目] Given a collection of integers that might contain duplicates, nums, return all possible subsets ...

  3. Leetcode之二分法专题-167. 两数之和 II - 输入有序数组(Two Sum II - Input array is sorted)

    Leetcode之二分法专题-167. 两数之和 II - 输入有序数组(Two Sum II - Input array is sorted) 给定一个已按照升序排列 的有序数组,找到两个数使得它们 ...

  4. Leetcode之回溯法专题-212. 单词搜索 II(Word Search II)

    Leetcode之回溯法专题-212. 单词搜索 II(Word Search II) 给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词. 单 ...

  5. Leetcode之回溯法专题-52. N皇后 II(N-Queens II)

    Leetcode之回溯法专题-52. N皇后 II(N-Queens II) 与51题的代码80%一样,只不过52要求解的数量,51求具体解,点击进入51 class Solution { int a ...

  6. Leetcode之回溯法专题-40. 组合总和 II(Combination Sum II)

    Leetcode之回溯法专题-40. 组合总和 II(Combination Sum II) 给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使 ...

  7. 【LeetCode】375. Guess Number Higher or Lower II 解题报告(Python)

    [LeetCode]375. Guess Number Higher or Lower II 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://f ...

  8. mysql学习 | LeetCode数据库简单查询练习

    力扣:https://leetcode-cn.com/ 力扣网数据库练习:https://leetcode-cn.com/problemset/database/ 文章目录 175. 组合两个表 题解 ...

  9. 功能齐全、效率一流的免费开源数据库导入导出工具(c#开发,支持SQL server、SQLite、ACCESS三种数据库),每月借此处理数据5G以上

    软件名:DataPie 功能:支持SQL server.SQLite.ACCESS数据库的导入.导出.存储过程调用,支持EXCEL2007.EXCEL2003.ACCESS2007. CSV文件导入数 ...

随机推荐

  1. TJOI2018简要题解

    Day1T1数学计算 按照时间轴建一棵线段树即可,复杂度为\(O(m \log m)\) #include <bits/stdc++.h> #define N 100005 #define ...

  2. MyBatis系列(二) MyBatis接口绑定与多参数传递

    前言 通过上一篇博文的,已经可以做到通过MyBatis连接数据库,现在再来介绍一种方法通过接口绑定SQL语句. 不使用接口绑定的方式 不使用接口绑定的方式,是通过调用SqlSession中的selec ...

  3. rsync+inotify实现多台服务器之间数据实时同步

    配置环境 1.操作系统:CentOS6.5-X86_64 2.rsync客户端(rsync+inotify):192.168.200.82 3.rsync服务端:192.168.200.80,192. ...

  4. 正则-RegExp

    正则-RegExp 正则,是一条规则,用于检验字符串格式,目标就是字符串: 只要是表单提交的数据都是字符串 定义: 1,var reg=/格式/ 2,var reg=new regexp() 方法: ...

  5. MFC 文件保存对话框的设置的那些秘密

    搬家自CSDN 2015-5-14 CFileDialog::CFileDialog( BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, LPCTSTR ...

  6. zynq7020开发板+ Z-turn调试计划

    参加米尔zynq7020开发板试用活动. 收到米尔z-turn板子后,焊接了一个JTAG转接板,以方便调试PL部分,对于后面的调试部分,主要分三个部分走:1.调试FPGA部分,实现逻辑控制外围简单的设 ...

  7. ASP.NET Core中使用Cache缓存

    ASP.NET Core中使用Cache缓存 缓存介绍: 通过减少生成内容所需的工作,缓存可以显著提高应用的性能和可伸缩性. 缓存对不经常更改的数据效果最佳. 缓存生成的数据副本的返回速度可以比从原始 ...

  8. Java 之 异常基础

    一.异常概念 异常:指的是程序在执行过程中,出现的非正常的情况,最终会导致 JVM 的非正常停止. 在 Java 等面向对象的编程语言中,异常本身就是一个类,产生异常就是创建异常对象并抛出了一个异常对 ...

  9. python学习之:序列类型 之列表,元组,range

    列表 列表是可变序列,通常用于存放同类项目的集合(其中精确的相似程度将根据应用而变化). class list([iterable]) 可以用多种方式构建列表: 使用一对方括号来表示空列表: [ ] ...

  10. Cheat Engine 指针

    打开游戏 扫描时间的流程就不多说了 扫描结果 寻找基地址 右击扫描到的地址,选择什么改写了这个地址 会弹出如下窗口 不用管这个窗口,去改变一下游戏时间,出现如下图 随便打开一个,找到了数据块地址和偏移 ...