Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 按共享第三个表中的值筛选两个表中数据的并集的最佳方法_Sql_Oracle - Fatal编程技术网

Sql 按共享第三个表中的值筛选两个表中数据的并集的最佳方法

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

例如,让我们假设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 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
就在这里,因为这两个集合由于类型文字的原因而不可合并。)第一个集合可能会扫描卖家两次。在sqlplus
set autotrace traceonly中运行,并运行每个查询几次。注意每个查询上使用的运行时和IO。