根据查询计数输出执行多次选择查询

时间:2018-07-31 02:22:13

标签: postgresql postgresql-9.5

我只想在下面的“测试”表中执行一次查询。但是我要查询以检查计数,如果计数大于1,则需要执行另一个查询。

任何人都将如何将测试表结果存储到变量中,然后从该变量返回到函数输出,以便仅查询“ test”表一次?

下面是一个示例,因为我的Prod表具有数百万条记录,并且在我多次查询时遇到性能问题:(

Here is a sample of the code:

DECLARE @Temp TABLE (
[MEM_ID] [varchar](10) NULL,
       [CALL_DATE] [datetime2](3) NULL,
       [CALL_TIME] [varchar](8) NULL,
       [OPER_CODE] [varchar](8) NULL,
       [TEXT_DEPT] [varchar](6) NULL,
       [CAT_DESC] [varchar](30) NULL
)

INSERT INTO @Temp
VALUES ('00000-1400', '2018-07-16 00:00:00.000','10:12:23','YYZ2500','SERV06','PLAN BENEFITS')
,('00000-1400', '2018-06-10 00:00:00.000','10:12:23','YYZ2500','SERV06','PLAN BENEFITS')
,('00000-1400', '2018-07-01 00:00:00.000','18:12:23','YYZ2500','SERV06','CLAIMS')
,('00000-1400', '2018-07-02 00:00:00.000','05:12:23','YYZ2500','SERV06','OTHER')
,('00000-1400', '2018-07-14 00:00:00.000','02:12:23','YYZ2500','SERV06','CLAIMS')
,('00000-1400', '2018-07-27 00:00:00.000','11:12:23','YYZ2500','SERV06','PLAN BENEFITS')
,('00000-1400', '2018-06-30 00:00:00.000','08:12:23','YYZ2500','SERV06','PLAN BENEFITS')
,('00000-1400', '2018-06-29 00:00:00.000','07:12:23','YYZ2500','SERV06','AUTHORIZATIONS')
,('00000-1400', '2018-06-29 00:00:00.000','07:26:23','YYZ2500','SERV06','AUTHORIZATIONS')
,('00000-1400', '2018-06-25 00:00:00.000','09:38:23','YYZ2500','SERV06','OTHER')


Select Calc.*, CASE WHEN Calc.Disposition = 'No subsequent within 14' THEN CONVERT(tinyint, 1) ELSE 0 END as FCR_Ind

From  (Select DISTINCT Final.RowID, Final.CallCount, Final.MEM_ID, Final.CALL_DATE, 
    Final.CALL_TIME, Final.CAT_DESC, Final.OPER_CODE, Final.TEXT_DEPT,
       CASE WHEN Final.[Had a subsequent within 14 days] IS NULL 
       THEN 'No subsequent within 14' ELSE Final.[Had a subsequent within 14 days]
       END as Disposition
       From  (Select *
 From (Select DISTINCT T1.RowID, T1.CallCount, T1.MEM_ID, T1.CALL_DATE, 
    T1.CALL_TIME, T1.CAT_DESC, T1.OPER_CODE, T1.TEXT_DEPT,
CASE WHEN T2.CALL_DATE BETWEEN T1.CALL_DATE AND DateAdd(DAY, 14, T1.CALL_DATE) AND T2.RowID <> T1.RowID AND T2.CALL_DATE <> T1.CALL_DATE OR T2.CALL_TIME BETWEEN T1.CALL_TIME AND DateAdd(HOUR, 24, T1.CALL_DATE) AND T2.RowID <> T1.RowID AND T2.CALL_DATE = T1.CALL_DATE THEN 'Had a subsequent within 14 days' END as Disposition                                                           
               From   (Select ROW_NUMBER() OVER (PARTITION BY MEM_ID ORDER BY MEM_ID,
              [CALL_DATE], CALL_TIME) AS RowID, Count(CALL_TIME) as CallCount,
  MEM_ID, [CALL_DATE], CALL_TIME, CAT_DESC, OPER_CODE, TEXT_DEPT
                       From @Temp
                       Group by MEM_ID, [CALL_DATE], CALL_TIME, CAT_DESC, OPER_CODE, 
                    TEXT_DEPT) as T1
        Inner Join  (Select ROW_NUMBER() OVER (PARTITION BY MEM_ID ORDER BY MEM_ID, 
                [CALL_DATE], CALL_TIME) AS RowID, Count(CALL_TIME) as
                CallCount, MEM_ID, [CALL_DATE], CALL_TIME, CAT_DESC,
                OPER_CODE, TEXT_DEPT
    From @Temp
                Group by MEM_ID, [CALL_DATE], CALL_TIME, CAT_DESC, OPER_CODE,
        TEXT_DEPT) as T2
                      ON   T1.MEM_ID = T2.MEM_ID AND T1.CAT_DESC = T2.CAT_DESC ) as Sub 

      PIVOT( MAX(Sub.Disposition)
FOR Sub.Disposition IN ([Had a subsequent within 14 days])) AS PivotTable) as Final) as Calc

2 个答案:

答案 0 :(得分:0)

编辑。

我可能误会了,一开始错过了一些东西。

根据您的示例,我假设您不关心“测试”查询中的精确记录数。如果仅返回一个记录,则只需要名字和姓氏;如果测试返回多个记录,则只需要执行并返回不同的查询,对吗?那么,为什么不将“测试”查询与另一个查询一起包装,将结果限制为2,则添加列count(*)over()来检查recordcount是否大于1。将结果插入简单变量,然后使用IF结构返回变量或其他查询。如果在查询末尾未进行排序,则限制2还可以提高“测试”查询的查询性能,从而减少行之间的联接数量。这样,您只需运行一次测试查询,即可获取必要的值并减少此函数使用的资源占用量。例如:

CREATE OR REPLACE FUNCTION lcdm_main.test(IN p_member_crn character varying)
  RETURNS TABLE(fname character varying, lname character varying) AS
$BODY$
declare

vfname text;
vlastname text;
countRow  integer;

BEGIN


 select q1.fname,q1.lastname, count(*) over() as cc
   from (
         select t.fname, t.lastname                                       
           from testq t 
          where t.email = p_member_crn limit 2 
        )q1

into vfname,vlastname,countRow;


if countRow > 1 then 
   RETURN QUERY select concat( error_msg_cd , error_msg_nm )::character varying ,  NULL:: character varying
   from lcdm_main.error  where error_Cndtn_nm ='SMRF';

ELSE

   fname := vfname;
   lname := vlastname;
   return next;

END IF ;


END; 

$BODY$
  LANGUAGE plpgsql VOLATILE SECURITY DEFINER
  COST 100
  ROWS 1000;

答案 1 :(得分:0)

在下面的线程中,没有解决方案,类似的问题仍然存在。

https://dba.stackexchange.com/questions/40214/postgresql-stored-procedure-to-return-rows-or-empty-set

感谢大家提供的不同方法。