对于每一行,在父表中有与其相关的有效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)