使用联合向 SQL 查询添加更多表

Posted

技术标签:

【中文标题】使用联合向 SQL 查询添加更多表【英文标题】:Adding more tables to an SQL query with a Union 【发布时间】:2018-02-15 22:10:05 【问题描述】:

我将 2 列(PaidGross 和 PaidDiscount)放在一个列(Amount)中作为我的结果。 (我没有尝试连接。我的结果将包含两列中的所有记录在一个列中)

基本查询是这样的:

SELECT PaidGross AS Amount, BillingID FROM APPaidInvDtl(noLock)

UNION ALL

SELECT PaidDiscount AS Amount, BillingID FROM APPaidInvDtl(noLock)

它返回 35706 条记录,似乎得到了我想要的,所以我想我已经弄清楚了那部分但是......

这是我的扩展查询,因为我也尝试包含其他表中的数据:

SELECT APPaidInvDtl.PaidGross AS Amount, APPaidInvDtl.BillingID, DocumentLinks.DocIDInternal, DocumentLinks.LinkDocIDInternal
FROM APPaidInvDtl
INNER JOIN DocumentLinks ON APPaidInvDtl.BillingID=DocumentLinks.DocIDInternal

UNION ALL

SELECT APPaidInvDtl.PaidDiscount AS Amount, APPaidInvDtl.BillingID, DocumentLinks.DocIDInternal, DocumentLinks.LinkDocIDInternal
FROM APPaidInvDtl
INNER JOIN DocumentLinks ON APPaidInvDtl.BillingID=DocumentLinks.DocIDInternal

我的扩展查询得到了 102408 条记录,所以很明显我做错了什么。我相信我需要在两个查询中获得完全相同数量的记录才能知道我获得了正确的数据。

感谢您对我应该尝试的任何帮助或想法!约旦


2018 年 3 月 16 日更新:

@Smog @shwant00 是的,你是对的。链接了多个文档,因此我尝试将其限制为某种类型的文档。文档之间的链接存储在 DocumentLinks 表中,但是 Documents 表是具有指定文档类型的表。所以我很难在正确的时间获取正确的数据。我最近的尝试给了我错误:“DocumentLinks.LinkDocIDInternal”无法绑定。”这是我最近的尝试:

SELECT APPaidInvDtl.PaidGross AS Amount, APPaidInvDtl.BillingID, Invoice.DocIDInternal, Invoice.DocYYMM, Invoice.Docseq, Checkrun.DocIDInternal, Checkrun.DocYYMM, Checkrun.Docseq, DocumentLinks.DocIDInternal, DocumentLinks.LinkDocIDInternal
FROM APPaidInvDtl(nolock)
INNER JOIN Documents Invoice ON APPaidInvDtl.BillingID=Invoice.DocIDInternal
INNER JOIN Documents Checkrun ON DocumentLinks.LinkDocIDInternal=Checkrun.DocIDInternal
INNER JOIN DocumentLinks ON APPaidInvDtl.BillingID=DocumentLinks.DocIDInternal WHERE Checkrun.Doctype=27

UNION ALL

SELECT APPaidInvDtl.PaidDiscount AS Amount, APPaidInvDtl.BillingID, Invoice.DocIDInternal, Invoice.DocYYMM, Invoice.Docseq, Checkrun.DocIDInternal, Checkrun.DocYYMM, Checkrun.Docseq, DocumentLinks.DocIDInternal, DocumentLinks.LinkDocIDInternal
FROM APPaidInvDtl(nolock)
INNER JOIN Documents Invoice ON APPaidInvDtl.BillingID=Invoice.DocIDInternal
INNER JOIN Documents Checkrun ON DocumentLinks.LinkDocIDInternal=Checkrun.DocIDInternal
INNER JOIN DocumentLinks ON APPaidInvDtl.BillingID=DocumentLinks.DocIDInternal WHERE Checkrun.Doctype=27

【问题讨论】:

一个APPaidInvDtl 行可能与多个DocumentLinks 相关,这会导致您在第二个查询中获得更多记录 是的,显然连接将负责增加行数。 题外话:不要使用 NOLOCK 提示,除非由于嵌套查询或触发器等的锁定问题而绝对需要。尤其是在处理货币金额时,如果同时发生更新,您将获得错误的数据。 @Smog @shwant00 是的,你是对的。链接了多个文档,因此我尝试将其限制为某种类型的文档。文档之间的链接存储在DocumentLinks 表中,但是Documents 表是具有指定文档类型的表。所以我很难在正确的时间获取正确的数据。我将在问题中添加我最近的尝试。 @user3088736 你得到的错误是因为你在Checkrun 加入之前而不是DocumentLinks 并且你正在引用它所以改变这些加入的顺序并重试 【参考方案1】:

这个怎么样?

with #tmp as (
SELECT PaidGross AS Amount, BillingID as BillingID FROM APPaidInvDtl(noLock)
UNION ALL
SELECT PaidDiscount AS Amount, BillingID as BillingID FROM 
APPaidInvDtl(noLock)
)

select t.Amount, t.BillingID, d.DocIDInternal,  d.LinkDocInternal 
from #tmp t 
inner join DocumnetLinks d on d.BillingID = t.BillingID 

【讨论】:

我很好奇你为什么用哈希字符来命名你的 CTE?我不确定这会改变行数,但这肯定是帮助 OP 理解问题的好方法。 您可以进一步过滤结果集或选择不同的。我一直都是这样做的,我猜是习惯的力量。【参考方案2】:

我猜如果您在联合中运行第一个选择,您将获得 51204 行。从 35706 增加是由 join 引起的,但从 51204 增加到 102408 是因为您使用了 union all。 Union all 不会过滤掉重复的行。您只需要使用联合,它将过滤掉重复的行并只返回不同的行。

【讨论】:

以上是关于使用联合向 SQL 查询添加更多表的主要内容,如果未能解决你的问题,请参考以下文章

SQL两张表联合查询

sql联合查询语句(两张表)

sql如何一对多联合查询

求三表联合查询的SQL查询语句

sql联合查询UNION问题

创建 ORACLE 查询 - 使用默认值查看和联合