0

假设我有一个Image带有 JSON 元列的表:

ID
1 {“尺寸”:80,“效果”:“模糊”}
2 {“大小”:200,“优化”:真}
3 {“颜色”:“#abcdef”,“ext”:“.jpg”}

我有一个像这样的表格类型的动态参数

钥匙 价值
尺寸 200
优化 真的

我应该如何编写查询来过滤 Meta 列的键值对与 param 表中的所有值匹配的行?

SELECT Id
FROM Image
WHERE (
  --?? all keys and values matched the param table
)
4

1 回答 1

0

这是一种类型的关系除法(有余数)问题,同时具有粉碎 JSON 的额外扭曲。

这类问题有多种解决方案。一种常见的解决方案是LEFT JOIN将除数除数,将其分组并检查是否有任何不匹配:

DECLARE @tmp TABLE (
  "Key" NVARCHAR(8) COLLATE Latin1_General_BIN2,
  "Value" NVARCHAR(4) COLLATE Latin1_General_BIN2
);

INSERT INTO @tmp
  ("Key", "Value")
VALUES
  ('size', '200'),
  ('optimize', 'true');
  
SELECT *
FROM Image i
WHERE EXISTS (SELECT 1
    FROM @tmp t
    LEFT JOIN OPENJSON(i.Meta) j ON t.[Key] = j.[key] AND t.Value = j.value
    HAVING COUNT(j.value) = COUNT(*)  -- all match
);

另一种解决方案是使用双精度NOT EXISTS没有匹配的键/值输入对

DECLARE @tmp TABLE (
  "Key" NVARCHAR(8) COLLATE Latin1_General_BIN2,
  "Value" NVARCHAR(4) COLLATE Latin1_General_BIN2
);

INSERT INTO @tmp
  ("Key", "Value")
VALUES
  ('size', '200'),
  ('optimize', 'true');
  
SELECT *
FROM Image i
WHERE NOT EXISTS (SELECT 1
    FROM @tmp t
    WHERE NOT EXISTS (SELECT 1
        FROM OPENJSON(i.Meta) j
        WHERE t.[Key] = j.[key] AND t.Value = j.value
    )
);

db<>小提琴

YMMV 关于哪种解决方案更快。

于 2022-01-27T10:51:07.357 回答