Skip to content
Advertisement

MS-Access Query to PostgreSQL View

I am converting a microsoft access query into a postgresql view. The query has obvious components that I have found reasonable answers to. However, I am still stuck on getting the final result:

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));

Realizing I need to use CASE SUM WHEN, here is what I have worked out so far:

    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));

The goal is to count the number of instances in which the Sec_ID has the following:

  • has (Type = LODE and Status = Active) = SUM integer
  • has (Type = LODE and Loc_Date between 8/31/2017 and 9/1/2018) = SUM Integer

My primary issue is getting a SUM integer to populate in the new columns

Advertisement

Answer

Case expressions are the equivalent to the Access IIF() functions, but WHEN isn’t a function so it isn’t used by passing a set of parameters. Think of it as being a tiny where clause instead, it evaluates one or more predicates to determine what to do, and the action taken is established by what you specify after 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
;

By the way, you should NOT be relying on MM/DD/YYYY as dates in Postgres

nb: Aggregate functions ignore NULL, take this example:

+----------+
| 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 |
+----------+-------------+
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement