Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PostgreSQL-所有(数组)运算符-建议_Postgresql_Plpgsql - Fatal编程技术网

PostgreSQL-所有(数组)运算符-建议

PostgreSQL-所有(数组)运算符-建议,postgresql,plpgsql,Postgresql,Plpgsql,示例代码如下:所有或任何操作员未工作。我需要比较数组的所有值 CREATE OR REPLACE FUNCTION public.sample_function( tt_sample_function text) RETURNS TABLE (..... ) LANGUAGE 'plpgsql' COST 100 VOLATILE ROWS 1000 AS $BODY$ declare e record; v_cnt IN

示例代码如下:所有或任何操作员未工作。我需要比较数组的所有值

CREATE OR REPLACE FUNCTION public.sample_function(
    tt_sample_function text)
    RETURNS TABLE (..... )
    LANGUAGE 'plpgsql'

    COST 100
    VOLATILE 
    ROWS 1000

AS $BODY$
declare 

    e record;
    v_cnt INTEGER:=0;
    rec record;
    str text;
    a_v text [];
    

BEGIN

    FOR rec IN ( SELECT * FROM json_populate_recordset(null::sample_function ,sample_function::json) )
        LOOP
            a_v:= array_append(a_v, ''''||rec.key || '#~#' || rec.value||'''');

        END LOOP;
        
    SELECT MAInfo.userid FROM
        (SELECT DISTINCT i.userid, 
               CASE WHEN (i.settingKey || '#~#' || i.settingvalue) = ALL (a_v)
                              THEN i.settingKey ||  '#~#' || 'Y'
                              ELSE i.settingKey ||  '#~#' || 'N' END
               AS MatchResult
        FROM public.sample_table i
        WHERE (i.settingKey || '#~#' || i.settingvalue) = ALL (a_v)
        GROUP BY i.userid, MatchResult) AS MAInfo
        
        GROUP BY MAInfo.userid
        HAVING COUNT(MAInfo.userid) >= 1;
    
    RETURN QUERY (....);
            
END;
$BODY$;     


输入为

SELECT public.sample_function(
    '[{"key":"devicetype", "value":"TestType"},{"key":"ostype", "value":"TestType"}]'
)

任何建议,为什么我的ALL操作员不工作。我的意思是它总是给假,它应该匹配所有的数组元素


注:数据当然在表中。

您将事情复杂化了。您不需要FOR循环或数组来进行比较。您可以在一个语句中完成这一切。不需要额外的类型或生成数组

函数的参数应该声明为
jsonb
,因为您显然希望在那里传递有效的JSON

我不明白你想用CASE表达式实现什么。WHERE子句只返回与本例中第一个条件匹配的行,因此永远不会到达第二个条件

我也不明白为什么会有这样的情况,因为您完全放弃了外部查询中的结果

但是尽可能保持原始结构,我认为您可以将其简化为一个CREATETABLE as语句,并摆脱所有数组处理

CREATE OR REPLACE FUNCTION public.sample_function(p_settings jsonb)
  RETURNS TABLE (..... )
  LANGUAGE plpgsql
AS $BODY$
declare 
...
begin

  CREATE TEMP TABLE hold_userID AS 
  SELECT MAInfo.userid 
  FROM (
    -- the distinct is useless as the GROUP BY already does that
    SELECT i.userid, 
           CASE 
             -- this checks if the parameter contains the settings key/value from sample_table
             -- but the WHERE clause already makes sure of that???
             WHEN p_settings @> jsonb_build_object('key', i.settingKey, 'value', i.settingvalue) 
               THEN i.settingKey ||  '#~#' || 'Y'
             ELSE i.settingKey ||  '#~#' || 'N' 
           END AS MatchResult
    FROM public.sample_table i
    WHERE (i.settingKey, i.settingvalue) = IN (select t.element ->> 'key' as key,
                                                      t.element ->> 'value' as value
                                               from jsonb_array_elements(p_settings) as t(element))
    GROUP BY i.userid, MatchResult
  ) AS MAInfo
  GROUP BY MAInfo.userid
  HAVING COUNT(MAInfo.userid) >= 1;

  return query ...;
end;
$body$

如果要检查某些用户是否具有传递给函数的所有设置,则实际上不需要大小写表达式,只需要具有适当的
条件

所以也许你想要这个:

CREATE TEMP TABLE hold_userID AS 
SELECT i.userid, 
FROM public.sample_table i
WHERE (i.settingKey, i.settingvalue) = IN (select t.element ->> 'key' as key,
                                                  t.element ->> 'value' as value
                                           from jsonb_array_elements(p_settings) as t(element))
GROUP BY i.userid
HAVING COUNT(*) = jsonb_array_length(p_settings);
或者:

SELECT i.userid 
FROM (
   select userid, settingkey as key, settingvalue as value
   from public.sample_table 
) i
group by i.userid 
HAVING jsonb_object_agg(key, value) = p_settings

我不明白你用的是什么样的表达方式。
WHERE
子句已经使用了
=ALL(…)
,因此将永远无法到达CASE表达式的ELSE部分。好的,谢谢,但是-1。使事情复杂化,因为这是一个部分,需求非常复杂,无法通过此实现。请忽略sql查询。2.在这里,我将不起作用,因为我必须匹配输入中的每个值(键和值),这就是为什么我试图与所有值进行比较。3.这里所有的操作员都在按照我的预期工作。有了IN运算符,我可以用一个简单的表结构来实现,在这里没有帮助。非常感谢!我把上述想法融入到我所有复杂的永无止境的解决方案中。它工作得很好,解决了我的一部分问题。再次感谢。“因为我必须匹配每个值”-这正是上次使用
count(*)=jsonb\u array\u length()
的查询所做的。CASE表达式无法实现这一点。我还添加了另一种检查“所有”设置的方法
SELECT i.userid 
FROM (
   select userid, settingkey as key, settingvalue as value
   from public.sample_table 
) i
group by i.userid 
HAVING jsonb_object_agg(key, value) = p_settings