【问题标题】:pgsql - how to get the sum of only the not null values in stored procedurepgsql - 如何仅获取存储过程中非空值的总和
【发布时间】:2017-12-03 04:56:07
【问题描述】:

我在 pgsql 中创建了一个存储过程。特定列中有一个 json 对象,我需要获取该 json 对象中数据的总和。它完美地工作,直到它遇到一个空值。 json 对象中的元素可以有空值。但是当我得到总和时,它给出了一个错误。

无法执行语句(22P02 - 7 - 错误:整数的无效输入语法:“”上下文:PL/pgSQL 函数 gettargetreports(date,date) 第 3 行,在 RETURN QUERY)

这是我的存储过程。我该如何解决这个问题。

CREATE OR REPLACE FUNCTION public.gettargetreports(
IN start_dates date,
IN end_dates date)
RETURNS TABLE(report_id integer, report_name text, profileid text, 
    conv integer, visits integer, avgtime integer, revenue integer, 
    backlink integer, newvisits integer, bouncerate integer, roomnights 
    integer, visibility integer, marketshare integer, pagesvisits integer, 
    transactions integer, domainauthority integer, seocontribution 
    integer, overallwebvisits integer, newvisitspercentage integer) AS
$BODY$
BEGIN 
RETURN QUERY (
    (SELECT
        rpt.report_id,
        rpt.report_name,
        rpt.report_data->>'profile' as profileId,
        sum((rpt.report_target_data->>'conv')::int)::int as conv,
        sum((rpt.report_target_data->>'visits')::int)::int as visits,
        sum((rpt.report_target_data->>'avgTime')::int)::int as avgTime,
        sum((rpt.report_target_data->>'revenue')::int)::int as revenue,
        sum((rpt.report_target_data->>'backlink')::int)::int as backlink,
        sum((rpt.report_target_data->>'newVisits')::int)::int as newVisits,
        sum((rpt.report_target_data->>'bounceRate')::int)::int as bounceRate,
        sum((rpt.report_target_data->>'roomNights')::int)::int as roomNights,
        sum((rpt.report_target_data->>'visibility')::int)::int as visibility,
        sum((rpt.report_target_data->>'marketshare')::int)::int as marketshare,
        sum((rpt.report_target_data->>'pagesVisits')::int)::int as pagesVisits,
        sum((rpt.report_target_data->>'transactions')::int)::int as transactions,
        sum((rpt.report_target_data->>'domainAuthority')::int)::int as domainAuthority,
        sum((rpt.report_target_data->>'seoContribution')::int)::int as seoContribution,
        sum((rpt.report_target_data->>'overallWebVisits')::int)::int as overallWebVisits,
        sum((rpt.report_target_data->>'newVisitsPercentage')::int)::int as newVisitsPercentage
    FROM public.proc_targetreport as rpt
    WHERE (
        rpt.start_date >= (date_trunc('MONTH', start_dates))::date AND
        rpt.end_date <= (date_trunc('MONTH', end_dates))::date 
        )
        GROUP BY rpt.report_id,rpt.report_name,profileId
    )
 );
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100
  ROWS 1000;

report_target_data 是 json 对象列名

【问题讨论】:

  • 我宁愿说,空值,而不是空值

标签: php mysql postgresql stored-procedures


【解决方案1】:

你可以尝试猴子破解,只有当你有正常的数值或空字符串时才会起作用,例如:

t=# select (concat('0',('{"s":null}'::json->>'s')))::int;
 concat
--------
      0
(1 row)

t=# select (concat('0',('{"s":""}'::json->>'s')))::int;
 concat
--------
      0
(1 row)

t=# select (concat('0',('{"s":29}'::json->>'s')))::int;
 concat
--------
     29
(1 row)

【讨论】:

  • 实际上 -&gt;&gt; 将 JSON null 转换为 SQL null。例如:select ('{"s":null}'::json-&gt;&gt;'s')::int; 也许 OP 有 "null" 值?
【解决方案2】:

JSON null 应转换为 SQL null。您可以将 SQL null 转换为 int 就好了:

select ('{"s":null}'::json->>'s')::int;
-->
NULL

但也许您使用的不是null,而是一个空字符串或"null" 字符串。在这种情况下,您可以使用case 进行翻译:

select case when col1 = 'xxx' then null else col1 end::int
from   (
       select '{"s":"xxx"}'::json->>'s' as col1
       ) sub1;
-->
NULL           

Example at rextester.

【讨论】:

  • sum((rpt.report_target_data::json-&gt;&gt;'conv')::int)::int as conv 这是正确的
  • 看起来不错,整数之和也是整数,所以外层的::int不是必须的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 2018-10-15
  • 1970-01-01
  • 1970-01-01
  • 2017-01-01
  • 2013-12-31
  • 2017-01-18
相关资源
最近更新 更多