没有合适的资源?快使用搜索试试~ 我知道了~
SQL之笛卡儿积的使用方法,适合SQL初学者
需积分: 5 0 下载量 200 浏览量
2024-05-16
09:47:18
上传
评论
收藏 2.74MB DOC 举报
温馨提示
试读
17页
在SQL中,笛卡儿积(Cartesian Product)是两个或多个表的组合,其中每一行都与另一个表中的每一行组合。简单来说,如果你有两个表A和B,A有a行,B有b行,那么A和B的笛卡儿积将是一个有a*b行的新表。 但是,在大多数实际场景中,我们并不直接使用笛卡儿积,因为它会产生大量的数据,并且通常这些数据不是我们真正需要的。然而,在SQL中,你可以通过简单地列出两个或多个表名(用逗号分隔)并使用SELECT语句来生成笛卡儿积。
资源推荐
资源详情
资源评论
笛卡儿积
笛卡儿积是将一个表或行集中的所有行与第二个表或行集中的所有行进行组合
的结果。虽然不像其他连接一样常见,但 CROSS JOIN(在 SQL 中创建笛卡儿积)
通常是创建 SQL 语句时必不可少的输入。
在本文中,将讨论几个除了使用笛卡儿积否则无法回答的真实问题。请注意,我
们不会讨论诸如在多列连接是忘记加上所需的一个或多个列而产生的错误笛卡
儿积。我们讨论的是刻意使用笛卡儿积且没有连接条件的情况。
我们认为,一旦你看到这个功能的用途,你会看到它能解决许多其他的问题。
1 生成两张表所有行的组合并标示一张表中间接关联另一张
表的列
有时候你需要生成各种组合的列表以判断哪些记录已经处理过而哪些还没有。
假设你希望找出每个客户买过什么与没买过什么产品。一个简单的方法是:
1) 生成客户和产品的所有可能组合的列表。
2) 生成每个客户的所有购买清单。
3)对所有可能组合的列表与实际的购买清单使用左连接,以标示出实际购买。
简单地列出每个客户购买的列表并不足以确定客户未购买什么。你还必须列出所
有可能的购买(即笛卡儿积)。对这两个结果集之间使用左连接(笛卡儿积为“左”
表,而实际购买为“右”表)时,你可以通过在“右侧”上判断空值来识别未购
买的产品。
你可以如代码清单 1 所示的 SQL 使用笛卡儿积产生一个 Customers 与 Products
的每个组合列表。
代码清单 1 使用笛卡儿积获得客户与产品的各种组合
SELECT c.CustomerID,c.CustFirstName,c.CustLastName,
p.ProductNumber,p.ProductName,p.ProductDescription
FROM Customers AS c, Products AS p;
虽然所有 DBMS 都支持在没有 JOIN 子句的 FROM 子句中列出表,但有些则会将
FROM 子句更改为 FROM Customer ASc CROSS JOIN Products AS p。
可以连接 Orders 与 Order_Details 表列出客户的购买清单,如代码清单 2 所示。
代码清单 2 找出所有销售的产品
SELECT o.OrderNumber, o.CustomerID,od. ProductNumber
FROM Orders AS o
INNER JOIN Order_Details AS od
ON o.OrderNumber - od.OrderNumber;
使用这两个查询,你可以使用左连接来确定笛卡儿积中的哪些行已被购买,哪些
行没有,如代码清单 3 所示。
代码清单 3 列出所有客户和所有产品,标示被客户购买过的产品
SELECT CustProd.CustomerID,CustProd.CustFirstName,
CustProd.CustLastName, CustProd.ProductNumber,
CustProd.ProductName.
(CASE WHEN OrdDet.OrderCount>0
THEN 'You purchased this!
' ELSE''
END) AS ProductOrdered
FROM
(SELECT c.CustomerID,c.CustFirstName,c.CustLastName,
p.ProductNumber, p.ProductName,p.ProductDescription
FROM Customers AS C, Products AS p) AS CustProd
LEFT JOIN
(SELECT o.CustomerID,od.ProductNumber,
COUNT(*) AS OrderCount
FROM Orders AS o
INNER JOIN Order_Details AS od
ON o.OrderNumber = od.OrderNumber
GROUP BY o.CustomerID,od.ProductNumber) AS OrdDet
ON CustProd.CustomerID-OrdDet.CustomerID
AND CustProd.ProductNumber= OrdDet.ProductNumber
ORDER BY CustProd.CustomerID,CustProd. ProductName;
相对于使用 LEFT JOIN,另一种方式是如代码清单 4 所示使用 IN 判断某个客户是
否购买过某个产品。不幸的是,我们无法告诉你哪一种方式比较好,因为性能取
决于数据量、索引以及你使用的 DMBS。
代码清单 4 列出所有客户和所有产品的替代方法,标记每个客户已经购买过的产品
SELECT c.CustomerID,c.CustFirstName,c.CustLastName,
p.ProductNumber,p.ProductName
(CASE WHEN C.CustomerID IN
(SELECT Orders.CustomerID
FROM Orders
INNER JOIN Order Details
ON Orders.OrderNumber = Order_Details,OrderNunber
WHERE Order_Details.ProductNumber = p.ProductNumber)
THEN "You purchased this!"
ELSE
END) AS ProductOrdered
FROM Customers AS c. Products AS p
ORDER BY c.CustomerID,p.ProductNumber;
两个查询的结果类似表 1 所示。
表 1 列出所有客户与所有产品,标示被客户购买过产品的部分结果总结
总结
□使用笛卡儿积产生两个表之间的各种组合。
□使用 INNER JOIN 确定实际发生的组合。
口使用 LEFT JOIN 将笛卡儿积的结果与实际发生的组合列表进行比较。
□你还可以使用 SELECT 子句中 CASE 语句中的 IN 子查询来产生与使用笛卡儿积
及 LEFT JOIN 相同的结果,但性能取决于数据量、索引和特定 DBMS。
2 理解如何以等分量排名
分析和比较结果时一无论是产品销售还是学生成绩一不仅要知道最好与最差,还
要知道特定值的排名区间。为此,你需要将排名等分,例如 4 等分(4 组)、5 等
分(5 组),或 10 等分(10 组)。这样不仅能够知道最好的学生或热卖产品,还能知道
前 10 或 20 名或前 25%的人。在本节中,我们将探讨如何制作这种排名与 5 等分
区间。
此例使用图 1 所示的销售订单数据库。
图 1 销售订单数据库的设计
找出特定产品类别销售状况也很有意思。在示例的数据库中,Accessories 类别
有很多产品,因此应该会产生更有趣的结果。
此查询中需要多个产品销售,因此使用公共表表达式(CTE)回传 Accessories 类别
中每个产品的总销售是合理的。你可以在代码清单 5 中看到 CTE 的 SQL。
剩余16页未读,继续阅读
资源评论
icysmile131
- 粉丝: 3058
- 资源: 107
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 百度地图,显示闸站分布,以及切换闸站位置,上传闸站图片信息的cordova插件,包含百度地图和百度定位库文件
- 基于合泰单片机的智能夹球小车(esp8266代码+k210代码+合泰单片机代码)
- 一个天气查询的安卓APP
- 基于CC2530+DHT11温湿度传感器实现物联网多传感器火灾报警系统
- 基于51单片机的简易计算器 / 具有加减乘除四则运算功能
- 学校端午节比赛dwj-master.zip
- 基于qt实现简单的加减乘除四则运算
- python爬虫案例python-graphs.rar
- python爬虫案例python-graphics.rar
- python爬虫案例python-geometry.rar
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功