使用 UNION 时 SQL 返回的结果更少?

发布于 2024-12-02 11:33:05 字数 3064 浏览 2 评论 0原文

我有一个 SQL Server 存储过程,当我添加联合和后半部分时,它不会给出所有结果。前半部分会给我所有 6 个结果,使用并集,我只得到 5 个。

有 3 个患者有自己的 [图表编号],每个患者都有 2 个应该显示的项目。如果患者的两个条目的 [CPTCode] 相同,则当我添加并集时,仅显示两个条目之一(它为我提供了所有 6 个具有相同 [cptcode] 且没有并集的条目)。后半部分实际上并没有从我现在正在做的事情中获取任何信息,但这是必要的。

select      /*Patients with chart numbers*/
   B1.[chart Number],
   '0' as newPatient, 
   isnull(Lytec.[Last Name],'') as [Last Name], 
   isnull(Lytec.[First Name],'') as [First Name],
   isnull(Address.[Name],
   Lytec.[Facility Code]) as [Facility], 
   isnull(B1.DOS,'') as [DOS], 
   isnull(Ins.[Name],
   Lytec.[Primary Code]) as [Primary Code],
   isnull(B1.[CPTCode],'') as cptCode, 
   isnull(B1.[Units],'') as [Units], 
   isnull(B1.[Modifiers],'') as [Modifiers], 
   isnull(B1.[cptCodeOther],'') as [cptCodeOther],
   isnull(B1.[cptCode2],'') as cptCode2, 
   isnull(B1.[Units],'') as [Units2], 
   isnull(B1.[Modifiers2],'') as [Modifiers2], 
   isnull(B1.[cptCodeOther2],'') as [cptCodeOther2],
   'name' as ProviderName
from 
   [sandboxmr].dbo.patient Lytec
   left join [dbo].[Billing] B1 on B1.[Chart Number] = Lytec.[Chart Number]
   left join [sandboxmr].dbo.[Address] Address on Lytec.[Facility Code] = Address.[Code]
   left join [sandboxmr].dbo.[Insurance] Ins on Lytec.[Primary Code] = Ins.[Code]
where 
   b1.[userid] = 54
   and (b1.[DateSubmitted] >= convert(varchar(25),'2011-8-31',101) 
   and b1.[DateSubmitted] <= convert(varchar(25),'2011-9-22',101))

union

select      /*Patients without chart numbers*/
   cast(P.id as varchar(15)) as [chart number], 
   '1' as newPatient,  
   isnull(P.[Last Name],'') as [Last Name], 
   isnull(P.[First Name],'') as [First Name],
   isnull(Address.[Name],
   P.[Facility Code]) as [Facility], 
   isnull(IV.DOS,isnull(SV.DOS,'')) as [DOS], 
   isnull(Ins.[Name],P.[Primary_Code]) as [Primary Code],
   isnull(IV.[cptCode],isnull(SV.[cptCode],'')) as cptCode, 
   isnull(IV.[Units],isnull(SV.[Units],'')) as [Units], 
   isnull(IV.[Modifiers],isnull(SV.[Modifiers],'')) as [Modifiers],    
   isnull(IV.[cptcodeother],isnull(SV.[cptcodeother],'')) as [cptCodeOther],
   isnull(IV.[cptCode2],isnull(SV.[cptCode2],'')) as cptCode2, 
   isnull(IV.Units2,isnull(SV.Units2,'')) as [Units2], 
   isnull(IV.[Modifiers2],isnull(SV.[Modifiers2],'')) as [Modifiers2], 
   isnull(IV.[cptCodeOther2],isnull(SV.[cptCodeOther2],'')) as [cptCodeOther2],
   'Name' as ProviderName
from 
   [DNSList].[dbo].[Patient] P 
   left join [dbo].[InitialVisits] IV on p.emr_id = IV.patientid
   left join [dbo].[SubsequentVisits] SV on p.emr_id = SV.patientid
   left join [sandboxmr].dbo.[Address] Address on P.[Facility Code] = Address.[Code]
left join [sandboxmr].dbo.[Insurance] Ins on P.[Primary_Code] = Ins.[Code]
where 
   p.[userid] = 54 
   and p.[Chart Number] is null
   and (p.[DateSubmitted] >= convert(varchar(25),'2011-8-31',101) 
   and p.[DateSubmitted] <= convert(varchar(25),'2011-9-22',101))
order by 
   [Last Name]

为什么会这样,我该如何解决它?我尝试将 distinct 添加到 [cptcode] 区域,但它当然会生成错误。

感谢您提供的任何帮助!

I have a SQL Server stored procedure that doesn't give me all the results when I add in the union and the second half. The first half will give me all 6 results, using the union, I only get 5.

There are 3 patients with their own [chart number], each have 2 items that should be displayed. if the [CPTCode] is the same for both entries of a patient, only one of the two entries show up when i add the union (it gives me all 6 with the same [cptcode] without the union). The second half isn't actually pulling any information with what i'm doing right now, but it is needed.

select      /*Patients with chart numbers*/
   B1.[chart Number],
   '0' as newPatient, 
   isnull(Lytec.[Last Name],'') as [Last Name], 
   isnull(Lytec.[First Name],'') as [First Name],
   isnull(Address.[Name],
   Lytec.[Facility Code]) as [Facility], 
   isnull(B1.DOS,'') as [DOS], 
   isnull(Ins.[Name],
   Lytec.[Primary Code]) as [Primary Code],
   isnull(B1.[CPTCode],'') as cptCode, 
   isnull(B1.[Units],'') as [Units], 
   isnull(B1.[Modifiers],'') as [Modifiers], 
   isnull(B1.[cptCodeOther],'') as [cptCodeOther],
   isnull(B1.[cptCode2],'') as cptCode2, 
   isnull(B1.[Units],'') as [Units2], 
   isnull(B1.[Modifiers2],'') as [Modifiers2], 
   isnull(B1.[cptCodeOther2],'') as [cptCodeOther2],
   'name' as ProviderName
from 
   [sandboxmr].dbo.patient Lytec
   left join [dbo].[Billing] B1 on B1.[Chart Number] = Lytec.[Chart Number]
   left join [sandboxmr].dbo.[Address] Address on Lytec.[Facility Code] = Address.[Code]
   left join [sandboxmr].dbo.[Insurance] Ins on Lytec.[Primary Code] = Ins.[Code]
where 
   b1.[userid] = 54
   and (b1.[DateSubmitted] >= convert(varchar(25),'2011-8-31',101) 
   and b1.[DateSubmitted] <= convert(varchar(25),'2011-9-22',101))

union

select      /*Patients without chart numbers*/
   cast(P.id as varchar(15)) as [chart number], 
   '1' as newPatient,  
   isnull(P.[Last Name],'') as [Last Name], 
   isnull(P.[First Name],'') as [First Name],
   isnull(Address.[Name],
   P.[Facility Code]) as [Facility], 
   isnull(IV.DOS,isnull(SV.DOS,'')) as [DOS], 
   isnull(Ins.[Name],P.[Primary_Code]) as [Primary Code],
   isnull(IV.[cptCode],isnull(SV.[cptCode],'')) as cptCode, 
   isnull(IV.[Units],isnull(SV.[Units],'')) as [Units], 
   isnull(IV.[Modifiers],isnull(SV.[Modifiers],'')) as [Modifiers],    
   isnull(IV.[cptcodeother],isnull(SV.[cptcodeother],'')) as [cptCodeOther],
   isnull(IV.[cptCode2],isnull(SV.[cptCode2],'')) as cptCode2, 
   isnull(IV.Units2,isnull(SV.Units2,'')) as [Units2], 
   isnull(IV.[Modifiers2],isnull(SV.[Modifiers2],'')) as [Modifiers2], 
   isnull(IV.[cptCodeOther2],isnull(SV.[cptCodeOther2],'')) as [cptCodeOther2],
   'Name' as ProviderName
from 
   [DNSList].[dbo].[Patient] P 
   left join [dbo].[InitialVisits] IV on p.emr_id = IV.patientid
   left join [dbo].[SubsequentVisits] SV on p.emr_id = SV.patientid
   left join [sandboxmr].dbo.[Address] Address on P.[Facility Code] = Address.[Code]
left join [sandboxmr].dbo.[Insurance] Ins on P.[Primary_Code] = Ins.[Code]
where 
   p.[userid] = 54 
   and p.[Chart Number] is null
   and (p.[DateSubmitted] >= convert(varchar(25),'2011-8-31',101) 
   and p.[DateSubmitted] <= convert(varchar(25),'2011-9-22',101))
order by 
   [Last Name]

Why does it do this, and how can I fix it? I've tried adding a distinct to the [cptcode] area, but it of course generates an error.

Thanks for any help you can provide!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

归途 2024-12-09 11:33:05

UNION 将消除重复的行,无论它们是位于两个结果集之间,还是像您的情况那样,仅位于一个结果集中。尝试使用 UNION ALL 代替。

UNION will eliminate duplicate rows, whether they come between the two result sets or, as in your case, within just one result set. Try using UNION ALL instead.

薄暮涼年 2024-12-09 11:33:05

我相信您需要使用UNION ALLUNION 默认情况下抑制重复项

I believe you need to use UNION ALL. UNION suppresses duplicates by default

浪菊怪哟 2024-12-09 11:33:05

这里有一点背景知识。从技术上讲,表格是一组行。这是数学意义上的集合。

数学集合的两个重要属性是:

  • 集合是无序的
  • 集合没有重复

项 第一点是为什么行顺序不可靠,除非添加 ORDER BY 子句。第二个是您应该始终拥有主键以确保每行确实不同的原因之一。

UNION 运算是一个集合运算,(a) 组合两个集合,(b) 生成一个集合。为了保持集合的完整性,UNION 将删除重复的行。

不幸的是,没有真正的方法可以保证两行是否相同,因此 SQL 将简单地比较 SELECT 子句中的值。如果这些值相同,则 SQL 会判定存在重复项。

这可能会导致一个夸张的示例:

SELECT state FROM customers
UNION
SELECT state FROM customers;

原则上,state 值会生成两次,重复的值会被删除,而您所拥有的是一种冗长的方式来表达SELECT DISTINCT

集合行为也是 SELECT 语句中不能使用 ORDER BY 子句的原因:一旦对数据集进行排序,它就不再是真正的集合。

(是的,您可以有一个 ORDER BY 子句,但它不附加到 SELECT 语句,而是附加到生成的 UNION) 。

当然,SQL 不仅仅是纯数学,因此它包含两个打破集合的功能:

  • 您可以使用 ORDER BY 子句对集合进行排序。

    但是,您只能在其余工作完成后才能执行此操作,这就是为什么它是最后一个子句。

  • 您可以使用 UNION ALL 子句包含重复项。

A little background here. Technically a table is a set of rows. This is in the mathematical sense of sets.

Two important properties of mathematical sets are:

  • A set is unordered
  • A set has no duplicates

The first point is why row order is not reliable unless you add an ORDER BY clause. The second is one reason you should always have a primary key to ensure that each rows is indeed distinct.

The UNION operation is a set operation and (a) combines two sets, (b) produces a set. In order to maintain the integrity of a set the UNION will remove duplicate rows.

Unfortunately, there is no real way of guaranteeing whether two rows are supposed to be same, so SQL will simply compare the values in the SELECT clauses. If those values are the same, then SQL decides there is a duplicate.

This can lead to an exaggerated example:

SELECT state FROM customers
UNION
SELECT state FROM customers;

In principle, the state value is produced twice, duplicate values are removed, and what you have is a long-winded way of saying SELECT DISTINCT.

The set behaviour is also why you can’t have an ORDER BY clause in the SELECT statements: once you order a data set, it is no longer a true set.

(Yes, you can have an ORDER BY clause, but it isn’t attached to a SELECT statement, but rather to the resulting UNION).

Of course, SQL isn’t just about pure mathematics, so it includes two features which break the set:

  • You can order a set with an ORDER BY clause.

    However, you can only do this after the rest of the work is complete, which is why it’s the last clause.

  • You can include duplicates using the UNION ALL clause.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文