【问题标题】:MS-Access Query to PostgreSQL ViewMS-Access 查询到 PostgreSQL 视图
【发布时间】:2018-12-06 01:34:00
【问题描述】:

我正在将 microsoft access 查询转换为 postgresql 视图。该查询具有明显的组件,我已经找到了合理的答案。但是,我仍然坚持得到最终结果:

SELECT All_Claim_Data.Sec_ID,
    Sum(IIf([Type]="LODE",IIf([Status]="Active",1,0),0)) AS LD_Actv, 
    Sum(IIf([Type]="LODE",IIf([Loc_Date]>#8/31/2017#,IIf([Loc_Date]<#9/1/2018#,1,0),0),0)) AS LD_stkd_17_18, 
    Sum(IIf([Type]="LODE",IIf([Loc_Date]>#8/31/2016#,IIf([Loc_Date]<#9/1/2017#,1,0),0),0)) AS LD_stkd_16_17,
    Sum(IIf([Type]="LODE",IIf([Loc_Date]<#1/1/1910#,IIf(IsNull([Clsd_Date]),1,(IIf([Clsd_Date]>#1/1/1900#,1,0))),0),0)) AS Actv_1900s, 
    Sum(IIf([Type]="LODE",IIf([Loc_Date]<#1/1/1920#,IIf(IsNull([Clsd_Date]),1,(IIf([Clsd_Date]>#1/1/1910#,1,0))),0),0)) AS Actv_1910s,
  FROM All_Claim_Data.Sec_ID,
  GROUP BY All_Claim_Data.Sec_ID,
  HAVING (((Sum(IIf([casetype_txt]="LODE",1,0)))>0));

意识到我需要使用 CASE SUM WHEN,这是我到目前为止所制定的:

    CREATE OR REPLACE VIEW hgeditor.vw_test AS
     SELECT All_Claim_Data.Sec_ID,
     SUM (CASE WHEN(Type='LODE' AND WHEN(Status='Active',1,0),0)) AS LD_Actv, 
     SUM (CASE WHEN(Type='LODE' AND WHEN(Loc_Date>'8/31/2017' AND Loc_Date<'9/1/2018',1,0),0),0)) AS LD_stkd_17_18,
     SUM (CASE WHEN(Type='LODE' AND WHEN(Loc_Date<'1/1/1910' AND (IsNull(Clsd_Date),1,(WHEN([Clsd_Date]>'1/1/1900',1,0))),0),0)) AS Actv_1900s
    FROM All_Claim_Data.Sec_ID,
    GROUP BY All_Claim_Data.Sec_ID,
    HAVING (((SUM(IIf(Type='LODE',1,0)))>0));

目标是统计 Sec_ID 具有以下内容的实例数:

  • 有(类型 = LODE 和状态 = 活动)= SUM 整数
  • 具有(类型 = LODE 和 Loc_Date 介于 2017 年 8 月 31 日和 2018 年 9 月 1 日之间)= SUM 整数

我的主要问题是获取一个 SUM 整数以填充到新列中

【问题讨论】:

  • when 不是一个函数,一个 case 表达式是这样形成的:case when ... then when ... then ... else ... end 你似乎在使用IF() 时使用
  • @Used_By_Already 我用这个例子作为参考:link
  • 是的,那个引用没问题,但这不是CASE WHEN(Type='LODE' AND WHEN(Status='Active',1,0),0))
  • 所以,基本上我不知道我的“THEN”语句会是什么样子.....
  • 在下面阅读我的答案。您实际上只是在原始中返回 1 或 0,所以 THEN 1 ELSE 0

标签: sql postgresql ms-access sum case


【解决方案1】:

大小写表达式等效于 Access IIF() 函数,但 WHEN 不是函数,因此不能通过传递一组参数来使用它。将其视为一个很小的 ​​where 子句,它评估一个或多个谓词以确定要做什么,并且采取的操作由您在 THEN 之后指定的内容确定。

CREATE OR REPLACE VIEW hgeditor.vw_test AS
SELECT
    All_Claim_Data.Sec_ID
  , SUM( CASE
        WHEN TYPE = 'LODE' AND
            STATUS = 'Active' THEN 1
        ELSE 0
    END ) AS LD_Actv
  , SUM( CASE
        WHEN TYPE = 'LODE' AND
            Loc_Date > to_date('08/31/2017','mm/dd/yyyy') AND
            Loc_Date < to_date('09/1/2018','mm/dd/yyyy')  THEN 1
        ELSE 0
    END ) AS LD_stkd_17_18
  , SUM( CASE
        WHEN TYPE = 'LODE' AND
            Loc_Date < to_date('1/1/1910','mm/dd/yyyy')  AND
            [Clsd_Date] > to_date('1/1/1900','mm/dd/yyyy')  THEN 1
        ELSE 0
    END ) AS Actv_1900s
FROM All_Claim_Data.Sec_ID
GROUP BY
    All_Claim_Data.Sec_ID
HAVING COUNT( CASE
    WHEN Type = 'LODE' THEN 1
END ) > 0
;

顺便说一句,你不应该依赖 MM/DD/YYYY 作为 Postgres 中的日期

nb:聚合函数忽略NULL,举个例子:

+----------+
| id value |
+----------+
| 1  x     |
| 2  NULL  |
| 3  x     |
| 4  NULL  |
| 5  x     |
+----------+

select
       count(*)      c_all
     , count(value)  c_value
from t

+-------+----------+
| c_all |  c_value |
+-------+----------+
|     5 |        3 |
+-------+----------+


select
       sum(case when value IS NOT NULL then 1 else 0 end) sum_case
     , count(case when value IS NOT NULL then 1 end)      count_case
from t

+----------+-------------+
| sum_case |  count_case |
+----------+-------------+
|        3 |           3 |
+----------+-------------+

【讨论】:

  • 请在这里询问这个答案
  • 请注意,在 Postgres 中 sum(case when value IS NOT NULL then 1 else 0 end) 也可以写成 count(*) filter (where value is not null) - 我觉得这更容易理解
  • 它没有被证明是“更明显的”,因为这是一个主观评估。对我来说,使用 sum() 来实现计数就更不明显了,不管你如何改写 case 表达式。
  • 嗯,我的表达确实使用count(*)来计数。
  • 是的,为此在我看来“更明显”。我怀疑我们在 rhat 上意见一致。我认为过滤器语法不太明显。但感谢您提醒我们另一种选择。
猜你喜欢
  • 2021-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多