Re: Limitting full join to one match - Mailing list pgsql-general

From Ron
Subject Re: Limitting full join to one match
Date
Msg-id 5d194157-789b-6e3c-4827-d462f58f0304@gmail.com
Whole thread Raw
In response to Limitting full join to one match  ("Phil Endecott" <spam_from_pgsql_lists@chezphil.org>)
Responses Re: Limitting full join to one match  ("Phil Endecott" <spam_from_pgsql_lists@chezphil.org>)
List pgsql-general
On 12/05/2018 06:34 PM, Phil Endecott wrote:
> Dear Experts,
>
> I have a couple of tables that I want to reconcile, finding rows
> that match and places where rows are missing from one table or the
> other:
>
> db=> select * from a;
> +------------+--------+
> |    date    | amount |
> +------------+--------+
> | 2018-01-01 |  10.00 |
> | 2018-02-01 |   5.00 |  <-- missing from b
> | 2018-04-01 |   5.00 |
> +------------+--------+
>
> db=> select * from b;
> +------------+--------+
> |    date    | amount |
> +------------+--------+
> | 2018-01-01 |  10.00 |
> | 2018-03-01 |   8.00 |  <-- missing from a
> | 2018-04-01 |   5.00 |
> +------------+--------+
>
> db=> select a.date, a.amount, b.date, b.amount from a full join b using (date,amount);
> +------------+--------+------------+--------+
> |    date    | amount |    date    | amount |
> +------------+--------+------------+--------+
> | 2018-01-01 |  10.00 | 2018-01-01 |  10.00 |
> | 2018-02-01 |   5.00 |            |        |
> |            |        | 2018-03-01 |   8.00 |
> | 2018-04-01 |   5.00 | 2018-04-01 |   5.00 |
> +------------+--------+------------+--------+
>
> This works fine until I have multiple items with the same date
> and amount:
>
> db=> select * from a;
> +------------+--------+
> |    date    | amount |
> +------------+--------+
> | 2018-01-01 |  10.00 |
> | 2018-02-01 |   5.00 |
> | 2018-04-01 |   5.00 |
> | 2018-05-01 |  20.00 |  <--
> | 2018-05-01 |  20.00 |  <--
> +------------+--------+
>
>
> db=> select * from b;
> +------------+--------+
> |    date    | amount |
> +------------+--------+
> | 2018-01-01 |  10.00 |
> | 2018-03-01 |   8.00 |
> | 2018-04-01 |   5.00 |
> | 2018-05-01 |  20.00 |  <--
> | 2018-05-01 |  20.00 |  <--
> +------------+--------+

What's your PK on "a" and "b"?

(Also, gmail seems to think that all -- or at least most -- of your email is 
spam.)

> db=> select a.date, a.amount, b.date, b.amount from a full join b using (date,amount);
> +------------+--------+------------+--------+
> |    date    | amount |    date    | amount |
> +------------+--------+------------+--------+
> | 2018-01-01 |  10.00 | 2018-01-01 |  10.00 |
> | 2018-02-01 |   5.00 |            |        |
> |            |        | 2018-03-01 |   8.00 |
> | 2018-04-01 |   5.00 | 2018-04-01 |   5.00 |
> | 2018-05-01 |  20.00 | 2018-05-01 |  20.00 |  1
> | 2018-05-01 |  20.00 | 2018-05-01 |  20.00 |  2
> | 2018-05-01 |  20.00 | 2018-05-01 |  20.00 |  3
> | 2018-05-01 |  20.00 | 2018-05-01 |  20.00 |  4
> +------------+--------+------------+--------+
>
> It has, of course, put four rows in the output for the new items.
>
> So my question is: how can I modify my query to output only two rows,
> like this:?
>
> +------------+--------+------------+--------+
> |    date    | amount |    date    | amount |
> +------------+--------+------------+--------+
> | 2018-01-01 |  10.00 | 2018-01-01 |  10.00 |
> | 2018-02-01 |   5.00 |            |        |
> |            |        | 2018-03-01 |   8.00 |
> | 2018-04-01 |   5.00 | 2018-04-01 |   5.00 |
> | 2018-05-01 |  20.00 | 2018-05-01 |  20.00 |  1
> | 2018-05-01 |  20.00 | 2018-05-01 |  20.00 |  2
> +------------+--------+------------+--------+
>
>
> Any suggestions anyone?
>
>
> The best I have found so far is something involving EXCEPT ALL:
>
> db=> select * from a except all select * from b;
> db=> select * from b except all select * from a;
>
> That's not ideal, though, as what I ultimately want is something
> that lists everything with its status:
>
> +------------+--------+--------+
> |    date    | amount | status |
> +------------+--------+--------+
> | 2018-01-01 |  10.00 |   OK   |
> | 2018-02-01 |   5.00 | a_only |
> | 2018-03-01 |   8.00 | b_only |
> | 2018-04-01 |   5.00 |   OK   |
> | 2018-05-01 |  20.00 |   OK   |
> | 2018-05-01 |  20.00 |   OK   |
> +------------+--------+--------+
>
> That would be easy enough to achieve from the JOIN.
>
>
> Thanks, Phil.
>
>
>

-- 
Angular momentum makes the world go 'round.


pgsql-general by date:

Previous
From: John W Higgins
Date:
Subject: Re: Limitting full join to one match
Next
From: bhargav kamineni
Date:
Subject: order of reading the conf files