我有两个表IAM和IAM_audit,如下所示。我正在尝试获取更改国家/地区或税国的帐号的结果。这很好。但是,我希望结果只显示唯一的帐号,即使它们在税国和国家/地区都已更改。我不希望这个例子中的帐号120显示两次? :)有办法吗。
初始表创建:
create table #Iam_audit1
(
accnum int,
invnumber int,
audit_field varchar(10),
field_before varchar(10),
field_after varchar(10),
modified_date datetime
)
insert into #Iam_audit1 (accnum, invnumber, audit_field, field_before,field_after, modified_date)
values
(120, 131, 'country', 'US', 'CAN','2014-08-09'),
(120, 131, 'taxcountry', 'US','CAN', '2015-07-09'),
(121, 132, 'country', 'CAN','US', '2014-09-15'),
(121, 132, 'taxcountry', 'CAN', 'US','2015-09-14'),
(122, 133, 'Taxcountry','CAN','US','2014-05-27')
create table #Iam
(
Accnum int,
invnumber int,
country varchar(10) ,
Taxcountry varchar(10)
)
insert into #Iam (Accnum, invnumber, country, taxcountry)
values (120, 131, 'CAN', 'CAN'),
(120, 132, 'US', 'US'),
(122, 133, 'CAN', 'CAN')
主要查询:
Select distinct IAMA.accnum,
IAMA.invnumber,
IAM.taxcountry,
Iama.audit_field,
IAM.country
From #iam_audit1 IAMA
join #IAM iam on iam.Accnum = iama.Accnum
AND iam.invnumber = iama.invnumber
Where Audit_Field IN ('TaxCountry', 'Country')
AND (
(isnull(Field_Before,'CAN') <> 'CAN' AND isnull(Field_After,'CAN') = 'CAN')
OR (isnull(Field_Before,'CAN') = 'CAN' AND isnull(Field_After,'CAN') <> 'CAN')
)
目前的结果
accnum invnumber taxcountry audit_field country
120 131 CAN country CAN
120 131 CAN taxcountry CAN
122 133 CAN Taxcountry CAN
预期结果:
accnum invnumber taxcountry audit_field country
120 131 CAN country CAN
122 133 CAN Taxcountry CAN
答案 0 :(得分:0)
只要exit
在select子句中,您就会有重复项。重构原始查询后,如果您的audit_field
表具有唯一帐号,即#IAM
,则可以看到它是唯一可能导致重复的字段。这是因为select子句中的所有其他列都可以来自accnum
表。
#IAM
根据您的特定使用要求(以及SQL Server的版本),如果您真的不希望单个帐号有多个记录,则可以尝试一些不同的解决方法。
首先,您可以从select子句中删除select distinct
IAM.accnum
, IAM.invnumber
, IAM.taxcountry
, IAMA.audit_field -- causing the 'duplicates' you describe
, IAM.country
from
#iam_audit1 IAMA
join
#IAM IAM
on
IAM.Accnum = IAMA.Accnum
and
IAM.invnumber = IAMA.invnumber
where
IAMA.Audit_Field IN ('TaxCountry', 'Country')
and (
(isnull(IAMA.Field_Before,'CAN') <> 'CAN' and isnull(IAMA.Field_After,'CAN') = 'CAN')
or
(isnull(IAMA.Field_Before,'CAN') = 'CAN' and isnull(IAMA.Field_After,'CAN') <> 'CAN')
)
。
audit_field
产生
select distinct
IAM.accnum
, IAM.invnumber
, IAM.taxcountry
, IAM.country
from
#iam_audit1 IAMA
join
#IAM IAM
on
IAM.Accnum = IAMA.Accnum
and
IAM.invnumber = IAMA.invnumber
where
IAMA.Audit_Field IN ('TaxCountry', 'Country')
and (
(isnull(IAMA.Field_Before,'CAN') <> 'CAN' and isnull(IAMA.Field_After,'CAN') = 'CAN')
or
(isnull(IAMA.Field_Before,'CAN') = 'CAN' and isnull(IAMA.Field_After,'CAN') <> 'CAN')
)
其次,您可以获取帐号和更改的不同audit_field的数量。
accnum invnumber taxcountry country
120 131 CAN CAN
122 133 CAN CAN
产生
select distinct
IAM.accnum
, IAM.invnumber
, IAM.taxcountry
, count(distinct IAMA.audit_field) as cnt_audits_with_changes
, IAM.country
from
#iam_audit1 IAMA
join
#IAM IAM
on
IAM.Accnum = IAMA.Accnum
and
IAM.invnumber = IAMA.invnumber
where
IAMA.Audit_Field IN ('TaxCountry', 'Country')
and (
(isnull(IAMA.Field_Before,'CAN') <> 'CAN' and isnull(IAMA.Field_After,'CAN') = 'CAN')
or
(isnull(IAMA.Field_Before,'CAN') = 'CAN' and isnull(IAMA.Field_After,'CAN') <> 'CAN')
)
group by
IAM.accnum
, IAM.invnumber
, IAM.taxcountry
, IAM.country
第三,如果您使用的是SQL Server 2017或更高版本,则可以使用string aggregate函数连接accnum invnumber taxcountry cnt_audits_with_changes country
120 131 CAN 2 CAN
122 133 CAN 1 CAN
audit_fields
产生
select distinct
IAM.accnum
, IAM.invnumber
, IAM.taxcountry
, string_agg(IAMA.audit_field, ', ') as list_audits_with_changes
, IAM.country
from
#iam_audit1 IAMA
join
#IAM IAM
on
IAM.Accnum = IAMA.Accnum
and
IAM.invnumber = IAMA.invnumber
where
IAMA.Audit_Field IN ('TaxCountry', 'Country')
and (
(isnull(IAMA.Field_Before,'CAN') <> 'CAN' and isnull(IAMA.Field_After,'CAN') = 'CAN')
or
(isnull(IAMA.Field_Before,'CAN') = 'CAN' and isnull(IAMA.Field_After,'CAN') <> 'CAN')
)
group by
IAM.accnum
, IAM.invnumber
, IAM.taxcountry
, IAM.country