一起使用SQL JOIN和UNION

时间:2011-08-16 17:42:03

标签: sql sql-server sql-server-2008 join union

好的,我难以理解为什么我会遇到以下行为。

我有一个“事务标题”表和“事务详细信息”表。对于某个功能,详细信息表需要一些标准化来提取“备注”数据。每个详细记录最多可以有3个备注,由TranRemark1,TranRemark2和TranRemark3列指定。

我把以下查询放在一起认为它会起作用,但它会返回错误的记录数。

SELECT  
b.ClientName,
a.TranID,
a.TranRemark1,
a.TranDateOfService,
a.TranPayment   
FROM
(select TranRemark1, TranID from TranDetail
union all
select TranRemark2, TranID from TranDetail
union all
select TranRemark3, TranID from TranDetail) AS a
LEFT JOIN TranHeader AS b ON
b.TranID = a.TranID
WHERE a.TranRemark1 = @RemarkCode;

我得到的结果集基于与ClientName匹配的TranHeader记录数,而不是与TranDetail中where子句匹配的记录数。例如,如果客户“Acme Inc.”在标题表中有3条记录,我使用上面的查询代码“1234”(在TranDetail中只匹配1条记录),结果集列出正确的记录3次。

修改的 所以我希望从上面的例子中得到这样的结果集:

ClientName--TranID--TranRemark1--TranDateOfService--TranPayment
Acme Inc    ADC11   1234         8-16-2011          45.11    

我得到的是:

ClientName--TranID--TranRemark1--TranDateOfService--TranPayment
Acme Inc    ADC11   1234         8-16-2011          45.11    
Acme Inc    ADC11   1234         8-16-2011          45.11  
Acme Inc    ADC11   1234         8-16-2011          45.11  

请记住,TranHeader中的客户端可能有多条记录。

我已经尝试过正确和完全加入,但这一切都是一样的。

我在哪里错过了这个问题?

感谢您的帮助。

4 个答案:

答案 0 :(得分:6)

你可以尝试更换:

LEFT JOIN TranHeader AS b ON
b.TranID = a.TranID
WHERE a.TranRemark1 = @RemarkCode;

使用:

LEFT JOIN
  ( SELECT DISTINCT
        TranId, ClientName
    FROM TranHeader
  ) AS b ON
b.TranID = a.TranID
WHERE a.TranRemark1 = @RemarkCode;

答案 1 :(得分:4)

怎么样

SELECT
  b.ClientName,
  a.TranID,
  a.TranRemark1,
  a.TranDateOfService,
  a.TranPayment
WHERE a.TranRemark1 = @RemarkID JOIN TranHeader b ON b.TranID = a.TranID
UNION ALL
SELECT
  b.ClientName,
  a.TranID
  a.TranRemark2,
  a.TranDateOfService,
  a.TranPayment
WHERE a.TranRemark2 = @RemarkID JOIN TranHeader b ON b.TranID = a.TranID
UNION ALL
SELECT
  b.ClientName,
  a.TranID,
  a.TranRemark3,
  a.TranDateOfService,
  a.TranPayment
WHERE a.TranRemark3 = @RemarkID JOIN TranHeader b ON b.TranID = a.TranID

我最初建议

SELECT  
b.ClientName,
a.TranID,
a.TranRemark1,
a.TranDateOfService,
a.TranPayment,
a.TranRemark1,
a.TranRemark2,
a.TranRemark3   
FROM
TranDetail a JOIN TranHeader As b ON
b.TranID = a.TranID
WHERE a.TranRemark1 = @RemarkCode 
  OR a.TranRemark2 = @RemarkCode 
  OR a.TranRemark3 = @RemarkCode;

但是您认为每个评论可能需要一个单独的行?

答案 2 :(得分:0)

如果执行UNION ALL,则在OUTER SQL上执行SELECT DISTINCT。 如果做UNION,它将处理重复项。

使用DISTINCT的UNION ALL可以提供更好的性能,但我相信......

答案 3 :(得分:0)

在获取数据时使用distinct

SELECT  distinct
b.ClientName,
a.TranID,
a.TranRemark1,
a.TranDateOfService,
a.TranPayment   
FROM`enter code here`
(select TranRemark1, TranID from TranDetail
union all
select TranRemark2, TranID from TranDetail
union all
select TranRemark3, TranID from TranDetail) AS a
LEFT JOIN TranHeader AS b ON
b.TranID = a.TranID
WHERE a.TranRemark1 = @RemarkCode;