【问题标题】:Outer join or dynamic query, which is the best way to go?外连接或动态查询,哪个是最好的方法?
【发布时间】:2010-11-20 11:33:07
【问题描述】:

我有以下表格(我已经简化了表格中包含的数据)。

RateTable
- rate_table_id [int]
- rate_table_name [nvarchar(50)]

RateTableUsed
- rate_used_id [int]
- rate_table_id [int] (key to RateTable.rate_table_id)
- customer_id [int] 

RateTableExtra
- rate_table_extra_id [int]
- rate_ extra_id [int] (key to RateExtra.rate_table_id)
- rate_used_id [int] (key to RateTableUsed.rate_used_id)

RateExtra
- rate_ extra_id [int]
- rate_extra_name [nvarchar(50)]


select rate_table_name, rate_table_extra_id, rate_extra_name from RateTableUsed rtu 
    innerjoin RateTable rt on rtu.rate_table_id = rt.rate_table_id 
    innerjoin RateTableExtra rte on rte.rate_table_id = rt.rate_table_id
    innerjoing RateExtr re on rte.rate_extra_id = re.rate_extra_id

RateExtra 仅包含 3 个值,键的 1、2 和 3 以及名称的汽油附加费、管理费和 GST。

这对于当前的目的来说工作正常。正在显示具有匹配记录的值列表,并且仅针对 rate_extra_name 查询 RateExtra。

所以我可能有以下结果:

  • Ratetable1, 1, 汽油附加费
  • Ratetable1、2、管理费
  • Ratetable2, 3, 汽油附加费
  • 税率表 4、4、GST
  • Ratetable6, 5, 汽油附加费

有人要求我对此进行修改,以便现在返回的每条记录都包含 RateExtra 表中每个值的记录。如果没有匹配的记录,那么我的 RateTableExtra 表中的数据应该返回为 NULL。所以我的数据应该返回为:

  • Ratetable1, 1, 汽油附加费
  • Ratetable1、2、管理费
  • Ratetable1,NULL,GST
  • Ratetable2, 3, PetrolSurcharge
  • Ratetable2,NULL,ManagementFee
  • Ratetable2,NULL,GST
  • Ratetable4,NULL,PetrolSurcharge
  • Ratetable4,NULL,ManagementFee
  • 税率表 4、4、GST
  • Ratetable6, 5, PetrolSurcharge
  • Ratetable6, NULL, ManagementFee
  • Ratetable6、NULL、GST

我已经尝试过 OUTER 连接,但我假设它们似乎不起作用,因为 RateExtra 数据链接到将返回 null 的 RateTableExtra。我现在正在考虑创建一个动态查询,该查询将获取我的原始结果集,对其进行迭代检查 rate_extra_id,如果它不在结果集中,则在我需要的带有 NULL 数据的结果中附加一个新行。我假设这会起作用,但我感觉它会成为性能的杀手。

有没有更好的方法来做到这一点?希望有人能帮忙,不胜感激。

【问题讨论】:

  • 如果您通过右连接使 RateTableExtra 成为可选,您还必须通过右连接使 RateExtra 成为可选。当事实上没有额外费用时,提出额外费用的原因是没有意义的。雅各布

标签: sql inner-join dynamic-sql outer-join


【解决方案1】:

试试这个:

select 
    rate_table_name, 
    rate_table_extra_id, 
    rate_extra
from 
    RateTableUsed rtu
    inner join RateTable rt on
        rtu.rate_table_id = rt.rate_table_id
    cross join RateExtra re
    left outer join RateTableExtra rte on 
        rte.rate_table_id = rt.rate_table_id
        and rte.rate_extra_id = re.rate_extra_id
order by rt.rate_table_name, re.rate_extra_id

您从这个查询中得到的本质上是RateTableRateExtra 之间的笛卡尔连接,并使用left join 查找与这些对匹配的RateTableExtra 的值。本质上,此查询将返回RateTableRateExtra所有可能的 组合,并快速显示RateTableExtra 表中有哪些组合。

小心笛卡尔连接。使用合理大小的桌子,他们可以很快失控! 享受吧!

【讨论】:

  • 你忘记了RateTableUsed,不过没关系,只要把它放在“from”之后(RateTableUsed rtu inner join RateTable rt on...)。 “order by”没有任何作用——将其改为“order by re.rate_extra_id”。
  • @Todd:我命名为RateTableUsed ru,而不是rtu,所以我的错。至于order by,确实有效果。否则,rate_table_name 将不正常。不过,应该是order by rt.rate_table_name, re.rate_extra_id,谢谢!
  • 使用没有 ON 子句的 CROSS JOIN 而不是 INNER JOIN .. ON 1 = 1 来编码笛卡尔连接会更清晰。
猜你喜欢
  • 2013-09-23
  • 2020-11-16
  • 1970-01-01
  • 2020-08-18
  • 2018-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多