简体   繁体   中英

Not in with variable is not working in where clause.... variable is a select query

I am trying to find out what is wrong to my query cause its not excluding the row that I want to exclude in not in clause. I really appreciate any suggestions. Thank you in advance

I have two tables

TableOne
 
Id     Name         isHealthy
1      Apple           Y
2      Banana          Y
3      Grapes          Y
4      Guava           Y
5      Orange          Y

TableX

Id     VALUE          isActive     DESCRIPTION
1      Apple,Banana       1        FRUITS
2      Orange             0        FRUITS
3      Grapes,Guava       1        FRUITS

I want to exclude in TableOne rows all column name the TableX Value

DECLARE @EXCLUDEVAL VARCHAR(max) = (SELECT ''''
          + Replace( String_agg([value], ','), ',', ''',''')
          + '''' AS EXCLUDEVAL
   FROM   tablex
   WHERE  [description] = 'FRUITS'
          AND isactive = '1');

SELECT *
FROM   tableone
WHERE  NAME NOT IN ( @EXCLUDEVAL ); 

I made this query however its not excluding the @EXCLUDEVAL will return this value

'Apple','Banana','Grapes','Guava' 

If I put the exact value without using variable @EXCLUDEVAL in the query it will work and exclude but I don't want hardcoded I want to use the variable @EXCLUDEVAL in where clause but I am not sure where I am going wrong.

You are mixing static and dynamic SQL - which doesn't work.

You are also following bad database design by storing multiple values in a single row and using a comma to separate them. The intention of a relational database is to store a single value per row/column. If you are able to change this it will make your life much easier for the future.

Assuming you can the full static version is:

SELECT *
FROM tableone
WHERE [NAME] NOT IN (
    SELECT [value]
    FROM tablex
    WHERE [description] = 'FRUITS'
    AND isactive = '1'
);

However if you are unable to change the design, and are using database compatibility 130 or better you can use STRING_SPLIT with CROSS APPLY to accomplish what you want.

SELECT *
FROM tableone
WHERE [NAME] NOT IN (
    SELECT R.Result
    FROM tablex X
    CROSS APPLY (
        SELECT [value] Result
        FROM STRING_SPLIT(X.[VALUE],',')
    ) R
    WHERE [description] = 'FRUITS'
    AND isactive = '1'
);

Or if you are using an older compatibility you need to implement your own string split function, of which there are many available with a quick google, and then CROSS APPLY again:

SELECT *
FROM tableone
WHERE [NAME] NOT IN (
    SELECT R.Result
    FROM tablex X
    CROSS APPLY dbo.MyStringSplitFunction(X.[Value],',') R
    WHERE [description] = 'FRUITS'
    AND isactive = '1'
);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM