我正在嘗試按 json 鍵動態分組以找到平均答案。
select
tbl.data->>'Example' as response,
count(tbl.data->>'Example') as total
from table tbl
group by tbl.data->>'Example'
order by total
limit 1
此查詢在 PostgreSQL 中運行時作業正常,我得到了我的預期結果:
| response | total |
|--------------------------|
| Hello World | 4 |
現在,當我不知道密鑰時,就會出現問題。它們是動態創建的,因此我需要遍歷它們。
$sql = <<<END
select
tbl.data->>? as response,
count(tbl.data->>?) as total
from table tbl
group by tbl.data->>?
order by total
limit 1
END;
$stmt = (new \PDO(...))->Prepare($sql);
$stmt->execute(array_fill(1, 3, 'Example'));
$stmt->fetch(\PDO::FETCH_ASSOC);
“示例”來自用戶輸入。JSON 由用戶創建,鍵可以是任何東西。在這種情況下,它是硬編碼的,但我運行一個單獨的 SQL 查詢來獲取所有鍵并回圈它們:
但我總是收到以下錯誤:
tbl.data 必須出現在 GROUP BY 子句中或在聚合函式中使用
現在,我假設這是因為準備好的陳述句將列視為資料,但此資訊來自用戶輸入,因此我需要使用準備好的陳述句。
select json_object_keys(data) as keys from table
對我如何解決這個問題有任何猜測嗎?
uj5u.com熱心網友回復:
我不知道php。但是從這個鏈接(https://kb.objectrocket.com/postgresql/postgres-stored-procedure-call-in-php-1475)看來,在 php 中使用函式似乎還不錯。
演示
CREATE OR REPLACE FUNCTION find_answer (_key text)
RETURNS json
AS $$
DECLARE
is_exists boolean;
_sql text;
_return json;
BEGIN
_sql := $sql$
SELECT
row_to_json(cte.*)
FROM (
SELECT
tbl.data ->> $1 AS response,
count(tbl.data ->> $1) AS total
FROM
tbl
GROUP BY
1
ORDER BY
total DESC
LIMIT 1) cte $sql$;
SELECT
(data[_key] IS NULL) INTO is_exists
FROM
tbl;
IF is_exists THEN
RAISE EXCEPTION '% not exists.', _key;
ELSE
RAISE NOTICE '% sql', _sql;
EXECUTE _sql
USING _key INTO _return;
RETURN _return;
END IF;
END
$$
LANGUAGE plpgsql;
然后呼叫它。select * from find_answer('example');
關于準備好的陳述
準備好的陳述句僅在當前 資料庫會話期間持續。當會話結束時,準備好的陳述句被遺忘,因此必須重新創建它才能再次使用。這也意味著單個準備好的陳述句不能被多個同時的資料庫客戶端使用;但是,每個客戶都可以創建自己的準備好的陳述句來使用。可以使用 DEALLOCATE 命令手動清理準備好的陳述句。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/480573.html
標籤:php json PostgreSQL 通过...分组
上一篇:在PostgreSQL中使用ALL進行SQL查詢的意外結果
下一篇:發現產品價格例外
