Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.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
Oracle SQL:联合和联接_Sql_Oracle_Join - Fatal编程技术网

Oracle SQL:联合和联接

Oracle SQL:联合和联接,sql,oracle,join,Sql,Oracle,Join,我有一个表ACCPLAN(主键:ACCOUNT\u ID) 我还有一个表ACCTRANSACTION(主键->(帐户ID,事务ID) 有5种固定计划类型和20种固定txn类型。只有少数交易类型是固定的 每个计划类型都可能。(例如:TXN类型1和TXN类型2可能用于 计划类型1和TXN类型2以及TXN类型3可用于计划类型2) 我正在尝试从ACCTRANSACTION和其他中检索交易信息 ACCP计划中的详细信息 这可以通过两种方式实现 方法1 检索每个计划类型并执行联合 select ap.acc

我有一个表ACCPLAN(主键:ACCOUNT\u ID)

我还有一个表ACCTRANSACTION(主键->(帐户ID,事务ID)

有5种固定计划类型和20种固定txn类型。只有少数交易类型是固定的 每个计划类型都可能。(例如:TXN类型1和TXN类型2可能用于 计划类型1和TXN类型2以及TXN类型3可用于计划类型2)

我正在尝试从ACCTRANSACTION和其他中检索交易信息
ACCP计划中的详细信息

这可以通过两种方式实现

方法1

检索每个计划类型并执行联合

select ap.account_id,ap.other_stuff,at.transaction_amount
from accplan ap, acctransaction at
where ap.account_id =  at.account_id
and ap.plan_type = PLAN_TYPE_ONE
and at.txn_type in (TXN_TYPE_1,TXN_TYPE_2);

union

select ap.account_id,ap.other_stuff,at.transaction_amount
from accplan ap, acctransaction at
where ap.account_id =  at.account_id
and ap.plan_type = PLAN_TYPE_TWO
and at.txn_type in (TXN_TYPE_2,TXN_TYPE_3); 

union

...
方法2

使用一个查询检索所有计划类型

 select ap.account_id,ap.other_stuff,at.transaction_amount
    from accplan ap, acctransaction at
    where ap.account_id =  at.account_id
    and 
    ((ap.plan_type = PLAN_TYPE_ONE  and at.txn_type in (TXN_TYPE_1,TXN_TYPE_2))

    or

    (ap.plan_type = PLAN_TYPE_TWO and at.txn_type in (TXN_TYPE_2,TXN_TYPE_3));

考虑到两个表都有大量数据,哪种方法更好?请建议。

使用联接。联接需要对整个结果进行排序,这对数据库来说是一项昂贵的操作

此外,最好只读取一次表并对每条记录进行一些复杂的检查,而不是只为了进行较小的检查而多次读取


免责声明:我可以想象一些非常奇怪的情况,第一个查询运行得更快,如果数据库查询规划者认为大的条件没有足够的选择性,没有使用索引,而每个较小的条件都使用索引。行数越大,我就越会使用第二个选项。

我投票关闭,因为你uestion是基于意见的,因此这是离题的。您应该对这两个查询运行解释说明,看看哪一个查询最适合您的数据库。我理解在这种情况下,“最佳”只意味着最快。在已知数据库(Oracle)中,这一点可以测量和复制。即使很多事情可能会影响结果(索引、统计信息、版本、配置选项、硬件)了解数据库的执行计划可以让您很好地了解什么可以更快。无论如何,定期会有许多与性能相关的问题可以重定向到某个stackexchange站点。Meta中是否有与此相关的内容?与您的问题无关:您应该停止使用过时的IMPLIT它在
where
子句中联接,并使用显式
JOIN
运算符(在
from
子句中)。我也同意第二个可能更有效。如果您确实想要第一个,您应该使用
UNION ALL
,以避免删除重复项的开销。+1很好的解释和免责声明。值得注意的是,Oracle确实有一些与
UNION
相关的不同转换,但没有其中一个应用于此处。例如,提示将
转换为
联合所有
,并可以防止在
联合所有
中重新读取大型表。奇怪的是,联合分解只适用于更复杂的场景,对这些简单的查询没有帮助。使用
联合所有
时可以避免排序而不是
UNION
UNION-ALL更快。如果他不介意重复,或者如果他确信没有重复,他可以使用它们。即使使用UNION-ALL,我也会打赌使用显式连接运算符进行连接,正如你所说的。
select ap.account_id,ap.other_stuff,at.transaction_amount
from accplan ap, acctransaction at
where ap.account_id =  at.account_id
and ap.plan_type = PLAN_TYPE_ONE
and at.txn_type in (TXN_TYPE_1,TXN_TYPE_2);

union

select ap.account_id,ap.other_stuff,at.transaction_amount
from accplan ap, acctransaction at
where ap.account_id =  at.account_id
and ap.plan_type = PLAN_TYPE_TWO
and at.txn_type in (TXN_TYPE_2,TXN_TYPE_3); 

union

...
 select ap.account_id,ap.other_stuff,at.transaction_amount
    from accplan ap, acctransaction at
    where ap.account_id =  at.account_id
    and 
    ((ap.plan_type = PLAN_TYPE_ONE  and at.txn_type in (TXN_TYPE_1,TXN_TYPE_2))

    or

    (ap.plan_type = PLAN_TYPE_TWO and at.txn_type in (TXN_TYPE_2,TXN_TYPE_3));