SQL Server选择组中的特定行

时间:2016-10-04 15:35:12

标签: sql sql-server window-functions

我正在使用SQL Server 2012.下面是一个示例数据集

Prefix_Suffix   First_Nm    Last_Nm Acct_Registration_Line_1    Acct_Registration_Line_2    secondlevel TopLevel
NULL    Jane    Smith   NULL    NULL    smith1-rep  abc-quarterly
NULL    John    Smith   NULL    NULL    smith1-rep  abc-quarterly
Jane Smith  NULL    NULL    IRA FBO Jane Smith (EQUITY) PERSHING LLC AS CUSTODIAN   smith1-rep  abc-quarterly
Jane Smith  NULL    NULL    IRA FBO Jane Smith (FI) PERSHING LLC AS CUSTODIAN   smith1-rep  abc-quarterly
John Smith  NULL    NULL    IRA FBO John Smith (EQUITY) PERSHING LLC AS CUSTODIAN   smith1-rep  abc-quarterly
John Smith  NULL    NULL    IRA FBO John Smith (FI) PERSHING LLC AS CUSTODIAN   smith1-rep  abc-quarterly

此数据以各种顺序出现,有时只有行填充First_Nm(名字)和Last_Nm(姓氏),Prefix_Suffix为NULL。有时会填充Prefix_Suffix,并且名字和姓氏字段为NULL。如果它是一个或所有其他为NULL,我可以处理。我正在努力的行是当两个NULL场景出现在一个组中时。通过在secondlevel列中具有相同的值来指示组。

如果在一个组中,Prefix_Suffix包含一个值,并且名字和姓氏都是null&还有一些行,其中名字和姓氏包含一个值,Prefix_Suffix为null那么我不希望任何具有Prefix_Sufix值的行。因此,当示例数据集发生时,我想过滤它以消除填充Prefix_Suffix的4行。同样,我只希望在Prefix_Suffix&之间具有交替NULLS的分组中获得此结果。 First_nm,Last_Nm。

期望的结果

Prefix_Suffix   First_Nm    Last_Nm Acct_Registration_Line_1    Acct_Registration_Line_2    secondlevel TopLevel
NULL    Jane    Smith   NULL    NULL    smith1-rep  abc-quarterly
NULL    John    Smith   NULL    NULL    smith1-rep  abc-quarterly

这是当前的select语句。我试图用UNION ALL隔离2个NULL场景,但这还不够。

WITH DATA AS
(
SELECT *,
COUNT(Acct_Nbr) OVER (PARTITION BY acct_nbr)AcctCount
 FROM ##temptable 
 WHERE  1 = 1
 AND acct_holder_role_cd <> 'sec'
)
SELECT * 
INTO ##PrefixedAccounts
FROM DATA
WHERE AcctCount = 1 AND Last_Nm IS NULL;
SELECT 
RcdTypId,Acct_Nbr,Acct_Short_Nm,Acct_Holder_Typ_Cd,Acct_Holder_Role_Cd, Prefix_Suffix
,First_Nm,Middle_Nm,Last_Nm,Acct_Registration_Line_1,Acct_Registration_Line_2
INTO ##temptable2
 FROM ##temptable 
WHERE NOT EXISTS
(
SELECT ##PrefixedAccounts.Acct_Nbr
FROM ##PrefixedAccounts 
WHERE ##PrefixedAccounts.Acct_Nbr = ##temptable.Acct_Nbr
);
WITH DATA AS
(
SELECT  
RcdTypId,Acct_Nbr,Acct_Short_Nm,Acct_Holder_Typ_Cd,Acct_Holder_Role_Cd,Prefix_Suffix,
NULL AS First_Nm, Middle_Nm, Last_Nm,Acct_Registration_Line_1,Acct_Registration_Line_2
FROM ##PrefixedAccounts
UNION ALL
SELECT
RcdTypId,Acct_Nbr,Acct_Short_Nm,Acct_Holder_Typ_Cd,Acct_Holder_Role_Cd,NULL AS Prefix_Suffix,First_Nm,Middle_Nm,Last_Nm,
NULL AS Acct_Registration_Line_1,NULL AS Acct_Registration_Line_2
FROM ##temptable2
)
SELECT * INTO ##ClientNames FROM DATA
DROP TABLE ##temptable2
DROP TABLE ##PrefixedAccounts

-- SELECT * FROM ##ClientNames ORDER BY prefix_Suffix desc
-- DROP TABLE ##ClientNames

SELECT distinct
cl.Prefix_Suffix,cl.First_Nm,cl.Last_Nm,cl.Acct_Registration_Line_1,cl.Acct_Registration_Line_2
,at.secondlevel,at.TopLevel FROM ##ClientNames cl
INNER JOIN ##AddeparTemplate at ON cl.Acct_nbr = at.owned
WHERE 1 = 1
AND (cl.Last_Nm IS NOT NULL OR cl.Acct_Registration_Line_1 IS NOT NULL)
ORDER BY cl.prefix_suffix, at.secondlevel
DROP TABLE ##ClientNames

1 个答案:

答案 0 :(得分:0)

这是你想要的吗?

select t.*
from (select t.*,
             row_number() over (partition by coalesce(prefix_suffix, first_nm + ' ' + last_nm)
                                order by (case when first_nm is not null then 1 else 2 end)
                               ) as seqnum
      from ##temptable t
     ) t
where seqnum = 1;