2017-06-21 59 views
2

目標是返回JSON數據類型中缺少某個鍵的所有記錄。這只是爲了明顯的,我想查詢JSON結構的任何東西,其中faultyField返回以下表中的數據中nullpostgresql未定義的json字段不會按預期返回null

id::SERIAL |  data::JSON 
------------+------------------- 
      1 | {"key" : "val"} 
      2 | {"key1" : "val2"} 

任何以下兩個語句:

SELECT * FROM test WHERE data->>'faultyField' = null; 
SELECT * FROM test WHERE (data->>'faultyField')::text = 'null'; 

應該返回所有的價值(根據我在工作中發現的兩個SO帖子)?但它不是因爲某種原因。這兩個只是返回空結果。

我不是使用PostgreSQL的嚮導,所以我嘗試了下面這些語句之間的所有內容,只是爲了看看它們是否可以工作。可悲的是,他們沒有。

SELECT * FROM test WHERE (SELECT json_object_keys(data) FROM test)='key'; 
SELECT * FROM test WHERE 'key' in json_object_keys(data); 
SELECT * FROM test WHERE 'key' := json_object_keys(data); 
SELECT * FROM test WHERE 'key' ANY (json_object_keys(data)); 

有沒有辦法返回JSON字符串中缺少密鑰的記錄?

回答

3

請勿使用=null。嘗試:

select * 
from test 
where data->>'faultyField' is null; 

the documentation

不要寫表達式= NULL因爲NULL是不 「等於」 NULL。 (NULL代表一個未知的值,它不知道兩個未知的數值是否相等。)

+0

我想操作系統試圖檢查一個密鑰是否存在,而不是測試它的值。在這種情況下,'data - >>'faultyField'爲null'將返回行,即使'faultyField'鍵存在並且具有空值。但我可能是錯的。 –

+0

呃,你錯了。 'data - >>'faultyField'爲null'當且僅當密鑰丟失時才爲真。 – klin

+0

你確定嗎? 'CREATE TEMP TABLE test AS SELECT 1 AS id,'{「key」:null}':: JSONB AS data; SELECT * FROM test WHERE data - >>'key'IS NULL;'。這個測試用例按我的預期返回該行。測試9.5.6。 –

4

編輯

我嚴重推薦您使用JSONB,而不是JSON。它是一個更強大的類型,它允許索引和其他運算符,如下面所示。


如果你想測試一個關鍵不在工作jsonb現場使用的頂級存在 ?操作:

CREATE TEMP TABLE test AS VALUES 
    (1, '{"key" : "val"}'::JSONB), 
    (2, '{"key2" : "val2"}'::JSONB); 

SELECT * FROM test WHERE NOT column2 ? 'key3'; 

使用data->>'faultyField'將嘗試獲得此鍵的值,而不是測試,如果鍵存在。這不是您要查找的內容,因爲它將返回行,即使faultyField鍵存在且具有空值。

+0

'沒有操作符匹配給定的名稱和參數類型。你可能需要在'?'上添加明確的類型轉換 - 爲什麼? – Torxed

+0

自9.4開始,'?'運算符就存在於'JSONB'類型中。什麼是您的PostgreSQL版本?有關[docs]的更多信息(https://www.postgresql.org/docs/current/static/functions-json.html)。 –

+0

我現在在搖擺v9.6.1。 JSONB用於字節數據tho? – Torxed