【MySQL】ANY函数 的巧用(筛选字段 = ANY(语句))

力扣题

1、题目地址

1364. 顾客的可信联系人数量

2、模拟表

顾客表:Customers

Column Name Type
customer_id int
customer_name varchar
email varchar
  • customer_id 是这张表具有唯一值的列。
  • 此表的每一行包含了某在线商店顾客的姓名和电子邮件。

联系方式表:Contacts

Column Name Type
user_id id
contact_name varchar
contact_email varchar
  • (user_id, contact_email) 是这张表的主键(具有唯一值的列的组合)。
  • 此表的每一行表示编号为 user_id 的顾客的某位联系人的姓名和电子邮件。
  • 此表包含每位顾客的联系人信息,但顾客的联系人不一定存在于顾客表中。

发票表:Invoices

Column Name Type
invoice_id int
price int
user_id int
  • invoice_id 是这张表具有唯一值的列。
  • 此表的每一行分别表示编号为 user_id 的顾客拥有有一张编号为 invoice_id、价格为 price 的发票。

3、要求

为每张发票 invoice_id 编写一个查询方案以查找以下内容:

  • customer_name:与发票相关的顾客名称。
  • price:发票的价格。
  • contacts_cnt:该顾客的联系人数量
  • trusted_contacts_cnt:可信联系人的数量:既是该顾客的联系人又是商店顾客的联系人数量
    (即:可信联系人的电子邮件存在于 Customers 表中)。
  • 返回结果按照 invoice_id 排序。

结果的格式如下例所示。

示例 1:

输入:
Customers 表:

customer_id customer_name email
1 Alice [email protected]
2 Bob [email protected]
13 John [email protected]
6 Alex [email protected]

Contacts 表:

user_id contact_name contact_email
1 Bob [email protected]
1 John [email protected]
1 Jal [email protected]
2 Omar [email protected]
2 Meir [email protected]
6 Alice [email protected]

Invoices 表:

invoice_id price user_id
77 100 1
88 200 1
99 300 2
66 400 2
55 500 13
44 60 6

输出:

invoice_id customer_name price contacts_cnt trusted_contacts_cnt
44 Alex 60 1 1
55 John 500 0 0
66 Bob 400 2 0
77 Alice 100 3 2
88 Alice 200 3 2
99 Bob 300 2 0

解释:
Alice 有三位联系人,其中两位(Bob 和 John)是可信联系人。
Bob 有两位联系人, 他们中的任何一位都不是可信联系人。
Alex 只有一位联系人(Alice),并是一位可信联系人。
John 没有任何联系人。

4、代码编写

代码

SELECT one.invoice_id, 
       two.customer_name, 
       one.price, 
       COUNT(three.user_id) AS contacts_cnt, 
       IFNULL(SUM(three.contact_email = ANY(SELECT email FROM Customers)), 0) AS trusted_contacts_cnt
FROM Invoices one
    LEFT JOIN Customers two ON one.user_id = two.customer_id
    LEFT JOIN Contacts three on two.customer_id = three.user_id
GROUP BY one.invoice_id
ORDER BY one.invoice_id

代码分析

1、根据发票找到对应顾客名称

SELECT two.customer_name
FROM Invoices one
	LEFT JOIN Customers two ON one.user_id = two.customer_id

2、从输出结果看出得根据发票 invoice_id 分组且排序根据发票 invoice_id 顺序,取得 发票价格

SELECT one.invoice_id, 
	   one.price
FROM Invoices one
GROUP BY one.invoice_id
GROUP BY one.invoice_id

3、顾客的联系人数量(Customers 顾客表对应 Contacts 联系人表)(two.customer_id = three.user_id)

SELECT COUNT(three.user_id) AS contacts_cnt
FROM Invoices one
    LEFT JOIN Customers two ON one.user_id = two.customer_id
    LEFT JOIN Contacts three on two.customer_id = three.user_id
GROUP BY one.invoice_id
ORDER BY one.invoice_id

4、可信联系人的数量是顾客联系人又是商店顾客的联系人数量,那就说明 Contacts 的对应联系人的邮箱存在于 Customers 表中

SELECT IFNULL(SUM(three.contact_email = ANY(SELECT email FROM Customers)), 0) AS trusted_contacts_cnt
FROM Invoices one
    LEFT JOIN Customers two ON one.user_id = two.customer_id
    LEFT JOIN Contacts three on two.customer_id = three.user_id
GROUP BY one.invoice_id
ORDER BY one.invoice_id

知识点

语法:筛选字段 = ANY(语句)
作用:只要 筛选字段 满足等于 语句 中的某一个值就返回True

语法:SUM(条件表达式)
作用:条件表达式如果为True,则加1,默认0(类似Count函数)

参考

SQL Any运算符

你可能感兴趣的:(#,MySQL,mysql)