【问题标题】:SQL to return unique combinations of non key columns within a set of key columnsSQL 返回一组键列中非键列的唯一组合
【发布时间】:2021-06-10 21:12:52
【问题描述】:

在 SQL Server 中,我有一个目标表 STAGNG_PA_BK_FEED_REVNU_SUM,它具有构成其唯一索引的以下 7 列。我想使用主要来自 STAGNG_PA_BK_FEED_REVNU_DTL 表的数据填充此表。目标表中的数据包括一个金额字段 REVNU_AMT,它是通过对所有其他选定/非聚合列进行分组来聚合的。

因为我们选择了不包含在目标表的唯一键中的附加“属性”列,如果我们在键组中为属性列获得多个不同的值组合,则插入将失败。发生这种情况时,我希望能够识别共享相同主键但具有不同属性值组合的所有源记录。换句话说,我希望能够生成完整源记录的报告,以便业务用户在插入时识别导致唯一键违规的违规记录。

INSERT INTO dbo.STAGNG_PA_BK_FEED_REVNU_SUM
    (
    --Keys of target table
    RBT_YR_DT
  , MLR_SRC_SYS_CD
  , LGL_ENTTY_CD
  , CLIENT_ID
  , CLIENT_ACCT_NUM
  , BEN_PLAN_ID
  , CLIENT_CNTRCT_ST_CD

    --Properties of target table
  , MLR_EXTRT_SYS_CD
  , PA_LGL_ENTTY_CD
  , COA_CO_CD
  , COMMRCL_BUS_IND
  , COA_SITUS_ST_CD
  , ASGND_SITUS_STE_IND
  , CLIENT_TY_CD
  , MLR_SEG_CD
  
  --Fact
  
  , REVNU_AMT
    
    )
SELECT
    --values for keys of target table
    D.RBT_YR_DT
  , D.MLR_SRC_SYS_CD
  , D.LGL_ENTTY_CD
  , D.CLIENT_ID
  , D.CLIENT_ACCT_NUM
  , D.BEN_PLAN_ID
  , J.SITUS_STE_CD   AS CLIENT_CNTRCT_ST_CD

    --values for properties of target table
  , D.MLR_EXTRT_SYS_CD
  , D.PA_LGL_ENTTY_CD
  , D.COA_CO_CD
  , D.COMMRCL_BUS_IND
  , D.COA_SITUS_ST_CD
  , 'N'              AS ASGND_SITUS_STE_IND   
  , D.CLIENT_TY_CD
  , D.MLR_SEG_CD

  --Fact
  ,SUM(D.REVNU_AMT) AS REVNU_AMT
  
FROM
    dbo.STAGNG_PA_BK_FEED_REVNU_DTL D
        INNER JOIN JE_NT_STE_MAP J
            ON D.COA_SITUS_ST_CD = J.CONTRACT_SITUS_STATE
GROUP BY
    --PK
    D.RBT_YR_DT
  , D.MLR_SRC_SYS_CD
  , D.LGL_ENTTY_CD
  , D.CLIENT_ID
  , D.CLIENT_ACCT_NUM
  , D.BEN_PLAN_ID
  , J.SITUS_STE_CD

    --Properties
    -- Must be unique distinct group of value within the key grouping else key violation on target will result
  , D.MLR_EXTRT_SYS_CD
  , D.PA_LGL_ENTTY_CD
  , D.COA_CO_CD
  , D.COMMRCL_BUS_IND
  , D.COA_SITUS_ST_CD
  , D.CLIENT_TY_CD
  , D.MLR_SEG_CD

更新

我之前考虑过使用 Jaime 将所有属性值连接成一个值的方法,以便可以在 HAVING 子句中应用 DISTINCT 动词。

接受他的回答,我修改它以显示报告源表中需要检查和更正的所有记录,以防止重复键违规,这是我的目标,而不仅仅是显示重复的非键价值观。

WITH DUPS AS
(
    SELECT
        --values for keys of target table
        D.RBT_YR_DT
      , D.MLR_SRC_SYS_CD
      , D.LGL_ENTTY_CD
      , D.CLIENT_ID
      , D.CLIENT_ACCT_NUM
      , D.BEN_PLAN_ID
      , J.SITUS_STE_CD              AS CLIENT_CNTRCT_ST_CD
    FROM
        dbo.STAGNG_PA_BK_FEED_REVNU_DTL D
            INNER JOIN JE_NT_STE_MAP J
                ON D.COA_SITUS_ST_CD = J.CONTRACT_SITUS_STATE
    GROUP BY
        --PK
        D.RBT_YR_DT
      , D.MLR_SRC_SYS_CD
      , D.LGL_ENTTY_CD
      , D.CLIENT_ID
      , D.CLIENT_ACCT_NUM
      , D.BEN_PLAN_ID
      , J.SITUS_STE_CD
    HAVING
        COUNT(DISTINCT
        CONVERT(VARCHAR(MAX), D.MLR_EXTRT_SYS_CD) + '-' +
        CONVERT(VARCHAR(MAX), D.PA_LGL_ENTTY_CD) + '-' +
        CONVERT(VARCHAR(MAX), D.COA_CO_CD) + '-' +
        CONVERT(VARCHAR(MAX), D.COMMRCL_BUS_IND) + '-' +
        CONVERT(VARCHAR(MAX), D.COA_SITUS_ST_CD) + '-' +
        CONVERT(VARCHAR(MAX), D.CLIENT_TY_CD) + '-' +
        CONVERT(VARCHAR(MAX), D.MLR_SEG_CD)
        ) > 1
)
SELECT
        --Keys
        D.RBT_YR_DT
      , D.MLR_SRC_SYS_CD
      , D.LGL_ENTTY_CD
      , D.CLIENT_ID
      , D.CLIENT_ACCT_NUM
      , D.BEN_PLAN_ID
      , D.COA_SITUS_ST_CD

      --Properties that have dups with a key groups
      , D.MLR_EXTRT_SYS_CD
      , D.PA_LGL_ENTTY_CD
      , D.COA_CO_CD
      , D.COMMRCL_BUS_IND
      , D.COA_SITUS_ST_CD
--      , 'N'              AS ASGND_SITUS_STE_IND   
      , D.CLIENT_TY_CD
      , D.MLR_SEG_CD

FROM
    STAGNG_PA_BK_FEED_REVNU_DTL D
        INNER JOIN JE_NT_STE_MAP J
                ON D.COA_SITUS_ST_CD = J.CONTRACT_SITUS_STATE
    inner join DUPS ON 

        DUPS.RBT_YR_DT           = D.RBT_YR_DT
    AND DUPS.MLR_SRC_SYS_CD      = D.MLR_SRC_SYS_CD
    AND DUPS.LGL_ENTTY_CD        = D.LGL_ENTTY_CD
    AND DUPS.CLIENT_ID           = D.CLIENT_ID
    AND DUPS.CLIENT_ACCT_NUM     = D.CLIENT_ACCT_NUM
    AND DUPS.BEN_PLAN_ID         = D.BEN_PLAN_ID
    AND DUPS.CLIENT_CNTRCT_ST_CD = J.SITUS_STE_CD

order by 1,2,3,4,5,6,7,8,9,10,11,12,13,14

虽然这在实践中可能有效,但我发现它有点笨拙,最后我可能会显示具有重复的非键的记录,该非键出现 另一个键分组但只出现在那里一次最终报告可能不准确。

【问题讨论】:

标签: sql sql-server tsql


【解决方案1】:

这样的东西可以帮助您找到具有超过 1 个不同属性组合的 PK

SELECT
   --values for keys of target table
   D.RBT_YR_DT
  ,D.MLR_SRC_SYS_CD
  ,D.LGL_ENTTY_CD
  ,D.CLIENT_ID
  ,D.CLIENT_ACCT_NUM
  ,D.BEN_PLAN_ID
  ,J.SITUS_STE_CD   AS CLIENT_CNTRCT_ST_CD
FROM dbo.STAGNG_PA_BK_FEED_REVNU_DTL D
  INNER JOIN JE_NT_STE_MAP J
    ON D.COA_SITUS_ST_CD = J.CONTRACT_SITUS_STATE
GROUP BY
   --PK
   D.RBT_YR_DT
  ,D.MLR_SRC_SYS_CD
  ,D.LGL_ENTTY_CD
  ,D.CLIENT_ID
  ,D.CLIENT_ACCT_NUM
  ,D.BEN_PLAN_ID
  ,J.SITUS_STE_CD
HAVING
    COUNT(DISTINCT
      CONVERT(VARCHAR(MAX),D.MLR_EXTRT_SYS_CD) + '-' +
      CONVERT(VARCHAR(MAX),D.PA_LGL_ENTTY_CD) + '-' +
      CONVERT(VARCHAR(MAX),D.COA_CO_CD) + '-' +
      CONVERT(VARCHAR(MAX),D.COMMRCL_BUS_IND) + '-' +
      CONVERT(VARCHAR(MAX),D.COA_SITUS_ST_CD) + '-' +
      CONVERT(VARCHAR(MAX),'N' AS ASGND_SITUS_STE_IND) + '-' +
      CONVERT(VARCHAR(MAX),D.CLIENT_TY_CD) + '-' +
      CONVERT(VARCHAR(MAX),D.MLR_SEG_CD)
    ) > 1

【讨论】:

  • 感谢您的回答,我认为它很有用,但我觉得它并不理想。在我更新的问题 cmets 中,我提到了我对生成报告的最终目标的担忧,该报告显示了共享相同键但具有不同非键列分组的所有记录的分组。即使最终结果是完美的,我觉得必须有一种更好的方法来连接单个字段中的非键列才能应用 DISTINCT 词。我非常感谢您的意见,我希望您不会因为我的保留而气馁。
  • 我想知道是否可以应用 PARTITION 窗口子句来识别键组中的多个非键分组...
  • 嗨@Chad,没问题...分区窗口函数不能与group by一起使用。此外,如果您想使用分区函数来获取此报告,这将更加复杂,因为例如使用 row_number,您需要按所有字段(键 + 属性)进行分区,识别这些键row_number > 2 很有趣。
  • 我知道,乍一看,这个解决方案似乎不是很有吸引力,但是处理这么多领域我想不出更干净的方法
【解决方案2】:

只使用窗口函数:

SELECT *
FROM (SELECT D.*, J.*,   -- may need to select particular columns to avoid duplicate column names
            COUNT(*) OVER (PARTITION BY D.RBT_YR_DT, D.MLR_SRC_SYS_CD, D.LGL_ENTTY_CD,
                                        D.CLIENT_ID, D.CLIENT_ACCT_NUM, D.BEN_PLAN_ID, J.SITUS_STE_CD,
                                        D.MLR_EXTRT_SYS_CD, D.PA_LGL_ENTTY_CD, D.COA_CO_CD, 
                                        D.COMMRCL_BUS_IND, D.COA_SITUS_ST_CD, D.CLIENT_TY_C
                          ) as cnt
      FROM dbo.STAGNG_PA_BK_FEED_REVNU_DTL D INNER JOIN
           JE_NT_STE_MAP J
           ON D.COA_SITUS_ST_CD = J.CONTRACT_SITUS_STATE
     ) DJ
WHERE cnt >= 2;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-10
    • 1970-01-01
    • 2015-05-21
    • 2014-01-06
    • 1970-01-01
    • 1970-01-01
    • 2012-08-20
    • 2017-04-23
    相关资源
    最近更新 更多