我正在使用 DB2,使用“数据”列,其中包含存储为 CLOB 的 JSON 对象。
为了简化我的场景,请考虑这个(更简单的)示例:
CREATE TABLE Students (
StudentID INT PRIMARY KEY NOT NULL,
Name VARCHAR(255),
PrefMeal CLOB
);
INSERT INTO Students (StudentID, Name, PrefMeal) VALUES
(1, 'John Doe', '{"pizza":[{"id":2,"name":"Pizza Patate e Salsiccia","ingredients":["Potatoes","Mozzarella Cheese","Sausage"]}]}'),
(2, 'Jane Doe', '{"pizza":[{"id":1,"name":"Pizza Margherita","ingredients":["Tomato Sauce","Mozzarella Cheese","Oregano"]}]}'),
(3, 'Mario Rossi', '{"pizza":[{"id":2,"name":"Pizza Patate e Salsiccia","ingredients":["Potatoes","Mozzarella Cheese","Sausage"]},{"id":1,"name":"Pizza Margherita","ingredients":["Tomato Sauce","Mozzarella Cheese","Oregano"]}]}');
SELECT s.*
FROM Students s
这当然会返回所有学生:
STUDENTID|NAME |PREFMEAL |
---------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1|John Doe |{"pizza":[{"id":2,"name":"Pizza Patate e Salsiccia","ingredients":["Potatoes","Mozzarella Cheese","Sausage"]}]} |
2|Jane Doe |{"pizza":[{"id":1,"name":"Pizza Margherita","ingredients":["Tomato Sauce","Mozzarella Cheese","Oregano"]}]} |
3|Mario Rossi|{"pizza":[{"id":2,"name":"Pizza Patate e Salsiccia","ingredients":["Potatoes","Mozzarella Cheese","Sausage"]},{"id":1,"name":"Pizza Margherita","ingredients":["Tomato Sauce","Mozzarella Cheese","Oregano"]}]}|
问题
现在,假设我想选择所有至少吃过“Pizza Margherita”的学生作为首选餐食。 通常 IN 运算符会发挥作用,但 $.pizza 是 JSON_ARRAY 并且更简单的解决方案不起作用(因此 json 路径也可以直接访问)...
我认为我可以使用 JSON_QUERY 函数来执行类似的操作:
SELECT S.NAME, JSON_QUERY(S.PREFMEAL, '$.pizza[*].name' WITH CONDITIONAL WRAPPER) AS PREF_PIZZA
FROM STUDENTS s
WHERE JSON_QUERY(S.PREFMEAL, '$.pizza[*].name') IN ('Pizza Margherita');
当然不会返回任何行,因为 JSON_ARRAY 和 IN 运算符的工作方式不同,而不是更简单的 ARRAY。
到目前为止我找到的唯一解决方案是以下一个,这对于某些 IN 比较当然是不可行的(太昂贵/太长):
我不喜欢迄今为止找到的唯一“解决方案”(这更像是一种解决方法),我认为这是不可行的,而且查询的成本和长度太昂贵(IN 中的多个值将被转换为许多 OR 条件):
SELECT *
FROM STUDENTS s
WHERE (JSON_QUERY(S.PREFMEAL, '$.pizza.name' WITH CONDITIONAL WRAPPER)) LIKE ('%"Pizza Margherita"%')
正确返回:
STUDENTID|NAME |PREFMEAL |
---------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
2|Jane Doe |{"pizza":[{"id":1,"name":"Pizza Margherita","ingredients":["Tomato Sauce","Mozzarella Cheese","Oregano"]}]} |
3|Mario Rossi|{"pizza":[{"id":2,"name":"Pizza Patate e Salsiccia","ingredients":["Potatoes","Mozzarella Cheese","Sausage"]},{"id":1,"name":"Pizza Margherita","ingredients":["Tomato Sauce","Mozzarella Cheese","Oregano"]}]}|
我已经没有想法了,我什至尝试过使用 JSON_TABLE 但找不到在Where 子句中正确使用它的方法。 任何帮助将不胜感激!
我只能支持亨里克。 BLOB 就是 BLOB,如果它的长度是 2GB,那么您的运行时间就不够理想。如果您将 JSON 取消嵌套到表中,Db2 有更好的方法来访问较大场景中所需的列。