T-SQL准备动态COALESCE

时间:2017-12-16 04:49:08

标签: sql-server coalesce

如屏幕截图所示,有两个表格。

  1. 配置
  2. enter image description here

    1. 详情
    2. 使用ConfigurationDetail表格,我想填充IdentificationType表格中的IDerivedIdentificationDetail列。

      应该使用以下逻辑,同时导出上面的列

      1. Configuration表具有优先顺序,用户可以动态更改(即,如果国家/地区为Austria,则ID首选项应为LEI,然后为TIN(如果LEI为空白),则为CONCAT(如果两个空白然后是其他逻辑)

      2. 如果合同ID = 3,国家/地区为BG,则应首先检查LEI,因为它的NULL,CCPT = 456将被选中。

      3. 如果允许硬编码,我可以使用COALESCECASE语句。

        请您建议任何替代方法吗?

        此致

        Digant

1 个答案:

答案 0 :(得分:0)

假设这是一些可怕的数据转储,并且您正在尝试清理它,这里有一些SQL可以抛出它。 :)首先,我能够通过Adobe Acrobat捕获您的图像文本> Excel中。

(我还在http://sqlfiddle.com/#!6/8f404/12

为您构建了架构

首先,正确的做法是解决明显的问题以及表结构。假设你无法在这里找到解决方案。

所以,它就是这样,它的作用是从详细信息表中删除列LEI,NIND,CCPT和TIN,以及从配置表中的FirstPref,SecondPref,ThirdPref。基本上,这样做有助于规范化数据,但如果没有计划修复数据结构或者您不能,则会使您的主要性能损失。之后,您只需将表格Detail.ContactId加入DerivedTypes.ContactId,然后DerivedPrefs.ISOCountryCode加入Detail.CountrylSOCountryCodeDerivedTypes.ldentificationType = DerivedPrefs.ldentificationType如果您使用内部联接而不是左联接,则可以删除RANK()函数但它不会显示所有ContactIds,只显示那些在LEI,NIND,CCPT或TIN列中具有值的那些。我认为这是一个更好的解决方案,因为你为什么要在报告中看到混合错误?为那些列中没有值的人写一份单独的报告。最后,TOP (1) with ties允许您为每个ContactId显示一条记录,并允许仍显示错误的记录。希望这会有所帮助。

CREATE TABLE Configuration
    (ISOCountryCode varchar(2), CountryName varchar(8), FirstPref varchar(6), SecondPref varchar(6), ThirdPref varchar(6))
;

INSERT INTO Configuration
    (ISOCountryCode, CountryName, FirstPref, SecondPref, ThirdPref)
VALUES
    ('AT', 'Austria', 'LEI', 'TIN', 'CONCAT'),
    ('BE', 'Belgium', 'LEI', 'NIND', 'CONCAT'),
    ('BG', 'Bulgaria', 'LEI', 'CCPT', 'CONCAT'),
    ('CY', 'Cyprus', 'LEI', 'NIND', 'CONCAT')
;


CREATE TABLE Detail
    (ContactId int, FirstName varchar(1), LastName varchar(3), BirthDate varchar(4), CountrylSOCountryCode varchar(2), Nationality varchar(2), LEI varchar(9), NIND varchar(9), CCPT varchar(9), TIN varchar(9))
;

INSERT INTO Detail
    (ContactId, FirstName, LastName, BirthDate, CountrylSOCountryCode, Nationality, LEI, NIND, CCPT, TIN)
VALUES
    (1, 'A', 'DES', NULL, 'AT', 'AT', '123', '4345', NULL, NULL),
    (2, 'B', 'DEG', NULL, 'BE', 'BE', NULL, '890', NULL, NULL),
    (3, 'C', 'DEH', NULL, 'BG', 'BG', NULL, '123', '456', NULL),
    (4, 'D', 'DEi', NULL, 'BG', 'BG', NULL, NULL, NULL, NULL)
;


SELECT TOP (1) with ties Detail.ContactId,
    FirstName,
    LastName,
    BirthDate,
    CountrylSOCountryCode,
    Nationality, 
    LEI, 
    NIND, 
    CCPT, 
    TIN, 
    ISNULL(DerivedPrefs.ldentificationType, 'ERROR') ldentificationType,
    IDerivedIdentification,
    RANK() OVER (PARTITION BY Detail.ContactId ORDER BY 
                    CASE WHEN Pref = 'FirstPref' THEN 1
                    WHEN Pref = 'SecondPref' THEN 2
                    WHEN Pref = 'ThirdPref' THEN 3
                    ELSE 99 END) AS PrefRank

FROM 
    Detail
LEFT JOIN   
(
    SELECT 
        ContactId, 
        LEI, 
        NIND,
        CCPT,
        TIN
    FROM Detail 
) DetailUNPVT
UNPIVOT
    (IDerivedIdentification FOR ldentificationType IN
        (LEI, NIND, CCPT, TIN)
    )AS DerivedTypes
ON DerivedTypes.ContactId = Detail.ContactId

LEFT JOIN 
(
    SELECT
        ISOCountryCode, 
        CountryName, 
        FirstPref, 
        SecondPref, 
        ThirdPref
    FROM
        Configuration
) ConfigUNPIVOT
UNPIVOT
    (ldentificationType FOR Pref IN
        (FirstPref, SecondPref, ThirdPref)
    )AS DerivedPrefs
ON DerivedPrefs.ISOCountryCode = Detail.CountrylSOCountryCode
and DerivedTypes.ldentificationType = DerivedPrefs.ldentificationType


ORDER BY RANK() OVER (PARTITION BY Detail.ContactId ORDER BY 
                    CASE WHEN Pref = 'FirstPref' THEN 1
                    WHEN Pref = 'SecondPref' THEN 2
                    WHEN Pref = 'ThirdPref' THEN 3
                    ELSE 99 END)