如果没有匹配项,子查询将返回所有行

时间:2019-01-07 21:56:50

标签: sql sql-server sql-server-2017

我正在使用JSON对象过滤WHERE子句中的数据。如果找到匹配项,则返回这些行,但是,如果没有匹配项,则返回所有行。

这是一个示例示例:

CREATE TABLE MyTable
(
   Id int identity(1,1) primary key,
   SomeObject varchar(20),
   SomeText varchar(20)
)
INSERT INTO MyTable(SomeObject, SomeText) VALUES ('hello', 'test1')
INSERT INTO MyTable(SomeObject, SomeText) VALUES ('yellow', 'test2')
INSERT INTO MyTable(SomeObject, SomeText) VALUES ('test1', 'test1')

使用的JSON过滤器:

DECLARE @Filter nvarchar(MAX)
SET @Filter = N'{
  "SomeObject": "ello,yel"
}'

在下面的示例中,要获取ello and yel列中带有SomeObject部分文本的行,我有以下工作查询。

SELECT mt.*
FROM MyTable mt
WHERE EXISTS (
   SELECT *
   FROM STRING_SPLIT(JSON_VALUE(@Filter, '$.SomeObject'), ',') 
   WHERE (mt.SomeObject LIKE CONCAT('%', [Value], '%'))

但是,如果我更改过滤条件并且未指定SomeObject

SET @Filter = N'{
}'

由于找不到匹配项,因此上述查询将不再起作用。为解决此问题,我尝试了以下两个查询,但仍未获得正确的输出。

1。

 --This query will ALWAYS return all the rows regardless of the filter being passed even though some of those will have a match.
SELECT mt.*
FROM MyTable mt
WHERE EXISTS (
   SELECT ISNULL(
   (
     SELECT *
     FROM STRING_SPLIT(JSON_VALUE(@Filter, '$.SomeObject'), ',') 
     WHERE (mt.SomeObject LIKE CONCAT('%', [Value], '%'))
    ),0)
 )

2。

--Works ONLY if filter specified. If filter is missing will not return all rows.
SELECT mt.*
FROM MyTable mt
WHERE EXISTS (
   SELECT *
   FROM STRING_SPLIT(JSON_VALUE(@Filter, '$.SomeObject'), ',') 
   WHERE (mt.SomeObject IS NULL AND JSON_VALUE(@Filter, N'$.SomeObject') IS 
      NULL OR mt.SomeObject LIKE CONCAT('%', [Value], '%'))
)

关于在subquery中找不到匹配项时如何返回所有行的任何建议?

1 个答案:

答案 0 :(得分:1)

如果您像上面一样默认设置过滤器,分别是{CR,然后是},则可以将此作为默认值:

SELECT mt.*
FROM MyTable mt
WHERE EXISTS (
   SELECT *
   FROM STRING_SPLIT(JSON_VALUE(@Filter, '$.SomeObject'), ',') 
   WHERE (mt.SomeObject LIKE CONCAT('%', [Value], '%')))
   OR replace(@Filter,char(10),'') = '{}'

否则,您可以通过将变量设置为NULL或空格或其他方式来解决此问题。在此处查看演示:DEMO