检查主表中是否存在合法值

时间:2016-02-02 08:14:15

标签: sql tsql

尊敬的Techie,请有人帮助我如何实现以下方案。

我有两张具有高度非规范化性质的表格Masterchild table

对于给定的特定行,有一些有效的脚注,我需要检查child table子表是否仅包含Master中存在的行的脚注。如果不是那个记录需要输出

DECLARE @MASTER TABLE
(
Footnote VARCHAR (50),
Line VARCHAR (50)
)

INSERT @MASTER

SELECT 'O031',  'EXHAUSTMUF' UNION ALL
SELECT 'V049',  'CAMSHAFT' UNION ALL
SELECT 'V049',  'DSHBRDCOVR' UNION ALL
SELECT 'V049',  'EXHAUSTMUF' UNION ALL
SELECT 'O040',  'EXHAUSTMUF' UNION ALL
SELECT 'V133',  'DSHBRDCOVR' UNION ALL
SELECT 'V133',  'EXHAUSTMUF' UNION ALL
SELECT 'E014',  'CAMSHAFT' UNION ALL
SELECT 'E014',  'EXHAUSTMUF' UNION ALL
SELECT 'O062',  'EXHAUSTMUF' UNION ALL
SELECT 'O194',  'EXHAUSTMUF'




DECLARE @ChildTable TABLE
(   
line    VARCHAR (50),
footnote_list VARCHAR (50)

)
INSERT @ChildTable

select 'EXHAUSTMUF',    'O031, V049' UNION ALL
select 'EXHAUSTMUF' ,'O040, V133' UNION ALL
select 'EXHAUSTMUF',    'E014, O062, O194' UNION ALL
select 'DSHBRDCOVR',    'USP2,LTS9' UNION ALL
select 'DSHBRDCOVR',    'V049' 

输出

DSHBRDCOVR  USP2,LTS9 

在输出中,因为DSHBRDCOVR行没有USP2或LTS9的脚注。

由于

1 个答案:

答案 0 :(得分:1)

首先添加一个功能:

create FUNCTION [dbo].[fnSplitString](     @string NVARCHAR(MAX),     @delimiter CHAR(1),   @keylist nvarchar(50)) 
RETURNS @output TABLE(splitdata NVARCHAR(MAX),keyName nvarchar(50)) 
BEGIN 
    DECLARE @start INT, @end INT 
    SELECT @start = 1, @end = CHARINDEX(@delimiter, @string) 
    WHILE @start < LEN(@string) + 1 BEGIN 
        IF @end = 0  
            SET @end = LEN(@string) + 1

        INSERT INTO @output (splitdata,keyName)  
        VALUES(ltrim(rtrim( SUBSTRING(@string, @start, @end - @start))),@keylist) 
        SET @start = @end + 1 
        SET @end = CHARINDEX(@delimiter, @string, @start)

    END 
    RETURN 
END

然后

DECLARE @MASTER TABLE
(
Footnote VARCHAR (50),
Line VARCHAR (50)
)

INSERT @MASTER

SELECT 'O031',  'EXHAUSTMUF' UNION ALL
SELECT 'V049',  'CAMSHAFT' UNION ALL
SELECT 'V049',  'DSHBRDCOVR' UNION ALL
SELECT 'V049',  'EXHAUSTMUF' UNION ALL
SELECT 'O040',  'EXHAUSTMUF' UNION ALL
SELECT 'V133',  'DSHBRDCOVR' UNION ALL
SELECT 'V133',  'EXHAUSTMUF' UNION ALL
SELECT 'E014',  'CAMSHAFT' UNION ALL
SELECT 'E014',  'EXHAUSTMUF' UNION ALL
SELECT 'O062',  'EXHAUSTMUF' UNION ALL
SELECT 'O194',  'EXHAUSTMUF'




DECLARE @ChildTable TABLE
(   
line    VARCHAR (50),
footnote_list VARCHAR (50)

)
--storing splitted values
DECLARE @SplittedTable TABLE
(   
splitted    VARCHAR (50),
keys VARCHAR (50)

)

INSERT @ChildTable

select 'EXHAUSTMUF',    'O031, V049' UNION ALL
select 'EXHAUSTMUF' ,'O040, V133' UNION ALL
select 'EXHAUSTMUF',    'E014, O062, O194' UNION ALL
select 'DSHBRDCOVR',    'USP2,LTS9' UNION ALL
select 'DSHBRDCOVR',    'V049' 

--getting max rows
declare @maxRows int =(SELECT count(*) FROM @childtable)

--loop over each rows
WHILE(@maxRows!=0)
BEGIN
DECLARE @footNotList nvarchar(max)=( SELECT abc.footnote_list FROM (SELECT ct.footnote_list, ROW_NUMBER() OVER (ORDER BY ct.footnote_list DESC) AS RowNumber
        FROM @ChildTable AS ct
)  abc WHERE abc.RowNumber=@maxRows )
--inserting into splitted table
INSERT INTO @SplittedTable
SELECT * FROM dbo.fnSplitString(@footNotList,',',@footNotList) 
set @maxRows=@maxRows-1;
END

--selecting by keys and finding them into master
SELECT * FROM @ChildTable ct WHERE ct.footnote_list IN (
SELECT DISTINCT st.keys FROM @SplittedTable AS st WHERE st.splitted  NOT IN (SELECT Footnote FROM @MASTER m ))

输出:

enter image description here

如果有任何问题,请告诉我。我测试了它