拆分逗号除拆分功能以外的其他值

时间:2016-04-04 07:20:27

标签: sql sql-server

对于每一行,在父表中有与其相关的有效Patient_id 我尝试验证正确的Patient_id是否与line相关联。

问题: 在子表中,Patient_id 以逗号分隔。 如果我使用函数来分割值,即使之后查询也没有完成 15个小时。

任何人都可以建议其他替代方案,如果可能的话请不要使用

DECLARE @PARENT_TABLE TABLE
(

Line VARCHAR (50),
Patient_id  VARCHAR (50)
)

INSERT @PARENT_TABLE

SELECT 'ABSRB', 'E001' UNION ALL
SELECT 'ABSRB', 'E067' UNION ALL
SELECT 'ABSRB', 'E068'



DECLARE @CHILD_TABLE TABLE
(
LINE VARCHAR (50),
SKU VARCHAR (50),
Patient_id VARCHAR (50)

)

INSERT @CHILD_TABLE

SELECT 'ABSRB', 'PRS317580',    NULL UNION ALL
SELECT 'ABSRB', 'RANRS7371',    'E001' UNION ALL
SELECT 'ABSRB', 'KYBKG54327',   'E067' UNION ALL
SELECT 'ABSRB', 'KYB344615',     'V048, V055, E068' UNION ALL
SELECT 'ABSRB', 'ZZZZ15245',     'S128, V048, V055'

SELECT * FROM @CHILD_TABLE

任何人都可以建议其他替代方案,如果可能的话请不要使用。

我这里没有包含分割功能代码。

代码:

CREATE FUNCTION [dbo].[fnSplitString](
   @string NVARCHAR(MAX),
   @delimiter CHAR(1),
   @keylist nvarchar(50)) 
  RETURNS TABLE
     AS
     RETURN(
     WITH CTE AS(
     SELECT 1 as n
     UNION ALL
     SELECT 1
     UNION ALL
     SELECT 1
     UNION ALL
     SELECT 1
     UNION ALL
     SELECT 1
     UNION ALL
     SELECT 1
     UNION ALL
     SELECT 1
     UNION ALL
     SELECT 1
     UNION ALL
     SELECT 1
     UNION ALL
     SELECT 1
     ),CTE2 AS(
         SELECT ROW_NUMBER() OVER(ORDER BY c.n) as n
         FROM CTE c
         CROSS JOIN CTE c2
         CROSS JOIN CTE c3
         CROSS JOIN CTE c4
         CROSS JOIN CTE c5
         CROSS JOIN CTE c6
     )

     SELECT TOP(LEN(COALESCE(@string,''))) 
       splitdata = ltrim(rtrim(
         SUBSTRING(@string, n, CHARINDEX(@delimiter, @string  + @delimiter, n)-n)
       )), 
       keyname= @keylist 
     FROM CTE2 
     WHERE n<= LEN(@string)
     AND SUBSTRING(@Delimiter + @string , n, LEN(@Delimiter)) = @Delimiter
     )



  DECLARE @SplittedTable TABLE
  (   
  splitted    VARCHAR (50),
  keys VARCHAR (50)
  )


  INSERT INTO @SplittedTable(splitted,keys)
     SELECT ss.splitdata, ss.keyname
     FROM @CHILD_TABLE ct 
     CROSS APPLY dbo.fnSplitString(ct.Patient_id,',',ct.Patient_id) ss



  SELECT * FROM @CHILD_TABLE ct WHERE ct.Patient_id IN (
  SELECT DISTINCT st.keys 
  FROM @SplittedTable AS st 
  WHERE st.splitted  NOT IN (SELECT Patient_id FROM @Parent_table m ));



      SELECT DISTINCT ct.*
      FROM @CHILD_TABLE ct 
      CROSS APPLY dbo.fnSplitString(ct.Patient_id,',',ct.Patient_id) ss
     WHERE ss.splitdata NOT IN (SELECT Patient_id FROM @Parent_table)

以下代码执行时间超过15小时。表格大小:20GB

CODE:

--selecting by keys and finding them into master

  SELECT * FROM @child ct WHERE ct.patientid IN (
  SELECT DISTINCT st.keys 
  FROM @SplittedTable AS st 
  WHERE st.splitted  NOT IN (SELECT patientid FROM @parent m ));


  --Use CROSS APPLY to get this done for all rows.
      SELECT DISTINCT ct.*
      FROM @child ct 
      CROSS APPLY dbo.fnSplitString(ct.patientid,',',ct.patientid) ss
     WHERE ss.splitdata NOT IN (SELECT patientid FROM @parent)

0 个答案:

没有答案