Sql 按共享第三个表中的值筛选两个表中数据的并集的最佳方法
例如,让我们假设3个表: 物理项目Sql 按共享第三个表中的值筛选两个表中数据的并集的最佳方法,sql,oracle,Sql,Oracle,例如,让我们假设3个表: 物理项目 ID SELLER_ID NAME COST DIMENSIONS WEIGHT 数字项目 ID SELLER_ID NAME COST DOWNLOAD_PATH 卖方 ID NAME 保证两个项目表中的项目ID都是唯一的。我想用类型标签按顺序选择给定卖家的所有商品ID。我想到了: 询问 SELECT PI.ID AS ID, 'PHYSICAL' AS TYPE FROM PHYSICAL_ITEM PI JOIN SELLE
ID
SELLER_ID
NAME
COST
DIMENSIONS
WEIGHT
数字项目
ID
SELLER_ID
NAME
COST
DOWNLOAD_PATH
卖方
ID
NAME
保证两个项目表中的项目ID都是唯一的。我想用类型标签按顺序选择给定卖家的所有商品ID。我想到了:
询问
SELECT PI.ID AS ID, 'PHYSICAL' AS TYPE
FROM PHYSICAL_ITEM PI
JOIN SELLER S ON PI.SELLER_ID = S.ID
WHERE S.NAME = 'name'
UNION
SELECT DI.ID AS ID, 'DIGITAL' AS TYPE
FROM DIGITAL_ITEM DI
JOIN SELLER S ON DI.SELLER_ID = S.ID
WHERE S.NAME = 'name'
ORDER BY ID
问题B
SELECT ITEM.ID, ITEM.TYPE
FROM (SELECT ID, SELLER_ID, 'PHYSICAL' AS TYPE
FROM PHYSICAL_ITEM
UNION
SELECT ID, SELLER_ID, 'DIGITAL' AS TYPE
FROM DIGITAL_ITEM) AS ITEM
JOIN SELLER ON ITEM.SELLER_ID = SELLER.ID
WHERE SELLER.NAME = 'name'
ORDER BY ITEM.ID
查询A似乎是最有效的,但它看起来也有不必要的重复(2个表连接到同一个表,2个where子句在同一个表列上)。查询B在某种程度上看起来更干净(没有重复),但它的效率也低很多,因为它有一个子查询。可以这么说,有什么办法可以两全其美呢?在这两种情况下,用
union all
替换union
<代码>联合不必要地删除重复项
我希望查询更高效,因为优化器在进行连接时有更多的信息(尽管我认为Oracle即使在联合之后也能很好地使用索引)。此外,第一个查询减少了联合之前的数据量
然而,这只是一种意见。真正的测试是对这两个查询进行计时——多次以避免缓存填充延迟——看看哪个更好。实际上,是对整个联合进行均匀排序,还是只对数字项子查询进行排序?我是否需要将其包装在outter select中才能订购整套产品?这就是订购整套产品。在union中,order by只允许出现在语句末尾,并应用于整个集合。。。我得到“SQL命令未正确结束”,这似乎与子查询结果的别名有关。您应该测试这两个查询。第二种可能更好,因为即使使用视图,Oracle也可以对其进行谓词推送(即,假设卖方在[name,id]上有一个索引,它可以选择扫描第一种,并在联合完成之前将谓词推送id到视图并连接到两个表上)[正如gordon所说,
union all
就在这里,因为这两个集合由于类型文字的原因而不可合并。)第一个集合可能会扫描卖家两次。在sqlplusset autotrace traceonly中运行,并运行每个查询几次。注意每个查询上使用的运行时和IO。