Re: Query help

From: Chuck Martin <clmartin(at)theombudsman(dot)com>
To: "Peter J(dot) Holzer" <hjp-pgsql(at)hjp(dot)at>
Cc: pgsql-general(at)lists(dot)postgresql(dot)org
Subject: Re: Query help
Date: 2019-01-27 23:50:05
Message-ID: CAFw6=U0+sR0EPe0BaaHnoGKiG8pehgH8qvSSriCgojwxWM-qhg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

On Sun, Jan 27, 2019 at 5:27 PM Chuck Martin <clmartin(at)theombudsman(dot)com>
wrote:

> On Sun, Jan 27, 2019 at 8:07 AM Peter J. Holzer <hjp-pgsql(at)hjp(dot)at> wrote:
>
>> On 2019-01-26 18:04:23 -0500, Chuck Martin wrote:
>> [snip]
>> > The idea should be obvious, but to explain, insdatetime is set when a
>> new
>> > record is created in any table. All records in ombcase have a foreign
>> key to
>> > status that can't be null. When status changes, a record is created in
>> > statuschange recording the old and new status keys, and the time (etc).
>> >
>> > The goal is to find records in ombcase that have not had a status
>> change in xx
>> > days. If the status has not changed, there will be no statuschange
>> record.
>>
>> The easiest way is to use set operations:
>>
>> select case_pkey from ombcase;
>> gives you all the ombcase ids.
>>
>> select ombcase_fkey from statuschange where insdatetime >= now()::date -
>> xx;
>> gives you all ombcase ids which had a status change in the last xx days.
>>
>> Therefore,
>> select case_pkey from ombcase
>> except
>> select ombcase_fkey from statuschange where insdatetime >= now()::date -
>> xx;
>> gives you all ombcase ids which did /not/ have a status change in the
>> last xx days.
>>
>
> I was not familiar with set operations, but studied up a bit and thought I
> was getting there. Not quite, though. I have two queries that individually
> return 1) all ombcase records with no statuschange record, and 2) the
> newest statuschange record for each case that has a statuschange record.
> But just putting UNION between then doesn't work. Here are my queries:
>
> --First, find all open cases with no statuschange record
> SELECT
>
> case_pkey,statuschange_pkey,case_fkey,ombcase.insdatetime,statuschange.insdatetime
> FROM
> ombcase
> LEFT JOIN
> statuschange
> ON
> statuschange.case_fkey = case_pkey
> AND case_pkey <> 0
> LEFT JOIN
> status
> ON status_fkey = status_pkey
> WHERE lower(statusid) NOT LIKE ('closed%')
> AND statuschange.statuschange_pkey IS NULL
> UNION
> --Now find the last status change record for each case that has one
> SELECT DISTINCT ON (case_fkey)
>
> case_pkey,statuschange_pkey,case_fkey,ombcase.insdatetime,statuschange.insdatetime
> FROM
> statuschange,ombcase,status
> WHERE case_fkey = case_pkey
> AND status_fkey = status_pkey
> AND LOWER(statusid) NOT LIKE ('closed%')
> ORDER BY case_fkey, statuschange.insdatetime DESC
>
> If I run each part separately, I get the expected number of records. When I combine them with UNION, I get "missing FROM-clause entry for table "statuschange"
> So I'm very close here, and these two return the exact number of records I'm expecting. So I just need to get them added together. Then I expect I can put the whole thing in a WHERE clause with "AND ombcase.case_pkey IN ([the combined results])"
>
> This was pretty easy to resolve. Putting parentheses around each half of
the query caused it to return the right results. Then I could reduce the
columns to just ombcase.case_pkey and use an IN statement. I think this
gets me where I need to be. I appreciate the help!

Chuck

In response to

Browse pgsql-general by date

  From Date Subject
Next Message Adrian Klaver 2019-01-28 01:18:08 Re: Error message restarting a database
Previous Message Hannes Erven 2019-01-27 23:21:41 Re: Does creating readOnly connections, when possible, free up resources in Postgres?