sql - SQL - UNION 与 NULL 函数。哪个更好?
问题描述
我有三个表:ACCT、PERS、ORG。每个 ACCT 由 PERS 或 ORG 拥有。PERS 和 ORG 表非常相似,它们的所有子表也是如此,但所有 PERS 和 ORG 数据都是独立的。
我正在编写一个查询来获取 ACCT 中每个帐户的 PERS 和 ORG 信息,我很好奇组合这些信息的最佳方法是什么。我应该使用一系列左连接和 NULL 函数来填补空白,还是应该单独编写查询并使用 UNION 组合?
我已经为 PERS ACCT 编写了单独的查询,为 ORG ACCT 编写了另一个查询,并计划使用 UNION。我的问题更多地与未来的最佳实践有关。
我希望两者都能给我想要的结果,但我想在开发时间和运行时间都找到最有效的方法。
编辑:样本表数据
ACCT表:
+---------+---------+--------------+-------------+
| ACCTNBR | ACCTTYP | OWNERPERSNBR | OWNERORGNBR |
+---------+---------+--------------+-------------+
| 555001 | abc | 3010 | |
| 555002 | abc | | 2255 |
| 555003 | tre | 5125 | |
| 555004 | tre | 4485 | |
| 555005 | dsa | | 6785 |
+---------+---------+--------------+-------------+
PERS 表:
+---------+--------------+---------------+----------+-------+
| PERSNBR | PHONE | STREET | CITY | STATE |
+---------+--------------+---------------+----------+-------+
| 3010 | 555-555-5555 | 1234 Main St | New York | NY |
| 5125 | 555-555-5555 | 1234 State St | New York | NY |
| 4485 | 555-555-5555 | 6542 Vine St | New York | NY |
+---------+--------------+---------------+----------+-------+
组织表:
+--------+--------------+--------------+----------+-------+
| ORGNBR | PHONE | STREET | CITY | STATE |
+--------+--------------+--------------+----------+-------+
| 2255 | 222-222-2222 | 1000 Main St | New York | NY |
| 6785 | 333-333-3333 | 400 4th St | New York | NY |
+--------+--------------+--------------+----------+-------+
期望的输出:
+---------+---------+--------------+-------------+--------------+---------------+----------+-------+
| ACCTNBR | ACCTTYP | OWNERPERSNBR | OWNERORGNBR | PHONE | STREET | CITY | STATE |
+---------+---------+--------------+-------------+--------------+---------------+----------+-------+
| 555001 | abc | 3010 | | 555-555-5555 | 1234 Main St | New York | NY |
| 555002 | abc | | 2255 | 222-222-2222 | 1000 Main St | New York | NY |
| 555003 | tre | 5125 | | 555-555-5555 | 1234 State St | New York | NY |
| 555004 | tre | 4485 | | 555-555-5555 | 6542 Vine St | New York | NY |
| 555005 | dsa | | 6785 | 333-333-3333 | 400 4th St | New York | NY |
+---------+---------+--------------+-------------+--------------+---------------+----------+-------+
查询选项 1:编写 2 个查询并使用 UNION 将它们组合起来:
select a.acctnbr, a.accttyp, a.ownerpersnbr, a.ownerorgnbr, p.phone, p.street, p.city, p.state
from acct a
inner join pers p on p.persnbr = a.ownerpersnbr
UNION
select a.acctnbr, a.accttyp, a.ownerpersnbr, a.ownerorgnbr, o.phone, o.street, o.city, o.state
from acct a
inner join org o on o.orgnbr = a.ownerorgnbr
选项 2:使用 NVL() 或 Coalesce 返回单个数据集:
SELECT a.acctnbr,
a.accttyp,
NVL(a.ownerpersnbr, a.ownerorgnbr) Owner,
NVL(p.phone, o.phone) Phone,
NVL(p.street, o.street) Street,
NVL(p.city, o.city) City,
NVL(p.state, o.state) State
FROM
acct a
LEFT JOIN pers p on p.persnbr = a.ownerpersnbr
LEFT JOIN org o on o.orgnbr = a.ownerorgnbr
在我的实际查询中,这 3 个表中的每一个都有更多的字段以及更多的 PERS 和 ORG 表。一种方法比另一种更好(更快,更有效)吗?
解决方案
这取决于您认为“更好”的内容。
假设您总是想从ACCT
表中提取所有行,我会说选择LEFT OUTER JOIN
and no UNION
。(如果使用UNION
,那么宁愿选择UNION ALL
变体。)
编辑:正如您已经展示了您的查询,我的不再需要,并且与您的结构不匹配。删除这部分。
为什么LEFT JOIN
?因为UNION
你必须通过ACCT
两次,基于“父”标准(无论是单独的还是完成的INNER JOIN
标准),而使用plain LEFT OUTER JOIN
,你可能只会通过一次ACCT
。在这两种情况下,来自“父母”的行很可能会根据主键来访问。
由于您可能正在考虑性能,因此在寻找“更好”时,一如既往:测试您的查询并查看执行计划,并根据数据“布局”(直方图等)提供足够和新鲜的数据库统计信息“更好”可能是完全不同的东西。
推荐阅读
- wordpress - 从 WordPress 网站自定义登录/重定向
- node.js - 查询数组时出现 MongoDB 数据匹配和获取问题
- pytorch - pytorch loss.backward() 持续运行数小时
- javascript - 合并两个代码
- android - 将 Jetpack Compose 添加到我现有的项目中
- node.js - 为什么当 ConsumedCapacity 超过预置吞吐量时 DynamoDB 没有拒绝?
- elasticsearch - 需要限制 Kibana 中的用户访问 EFK 中的特定应用程序日志
- python - Python Dataframe获取每行最后一个非空列的值
- javascript - 如何在本机反应中的数组过滤器响应值后禁用按钮
- sql - 如何使此查询更具可读性?