Postgres query issue with price matching with two tables

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Postgres query issue with price matching with two tables



I have two tables, one is buy table and second is sell table.



Buy Table


id price qty in_status dt_added_at
1 10 15 1 2018-08-10 12:00:00+05:30
2 10 20 1 2018-08-10 13:00:00+05:30
3 12 15 1 2018-08-10 14:00:00+05:30
4 15 20 1 2018-08-10 15:00:00+05:30



Sell Table


id price qty in_status dt_added_at
1 15 20 1 2018-08-10 12:00:00+05:30
2 12 15 1 2018-08-10 13:00:00+05:30
3 10 15 1 2018-08-10 14:00:00+05:30
4 10 20 1 2018-08-10 15:00:00+05:30
5 10 15 1 2018-08-10 16:00:00+05:30



Applied query of price matching table


SELECT buy.*, sell.* FROM buy
LEFT JOIN sell ON
buy.price = sell.price AND buy.qty = sell.qty
WHERE buy.price = 10 AND buy.in_status = 1 AND sell.price = 10 AND
sell.in_status = 1
GROUP BY buy.id, sell.id, buy.dt_added_at, sell.dt_added_at
ORDER BY buy.id, sell.id



Actual Output


id price qty in_status dt_added_at id price qty in_status dt_added_at
1 10 15 1 2018-08-10 12:00:00+05:30 3 10 15 1 2018-08-10 14:00:00+05:30
1 10 15 1 2018-08-10 12:00:00+05:30 5 10 15 1 2018-08-10 16:00:00+05:30
2 10 20 1 2018-08-10 13:00:00+05:30 4 10 20 1 2018-08-10 15:00:00+05:30



So here the 1st record of buy table is matched with the 3rd and 5th record of sell table but the 5th record should get omit because I need to implement FIFO and one buy record matched with one sell entry only and 2nd record of buy table is matched with the 4th record.



Expected Output


id price qty in_status dt_added_at id price qty in_status dt_added_at
1 10 15 1 2018-08-10 12:00:00+05:30 3 10 15 1 2018-08-10 14:00:00+05:30
2 10 20 1 2018-08-10 13:00:00+05:30 4 10 20 1 2018-08-10 15:00:00+05:30



You can see in below image.



enter image description here



Edited at 18thAug2018 - Tried with this data and it not works
As the entry of sell table is repeated.


CREATE TABLE Buy(
id int,
price int,
qty int,
in_status int,
dt_added_at timestamp
);

insert into Buy values (1,10,15,1,'2018-08-10 12:00:00+05:30');
insert into Buy values (2,10,20,1,'2018-08-10 13:00:00+05:30');
insert into Buy values (3,10,15,1,'2018-08-10 14:00:00+05:30');
insert into Buy values (4,10,20,1,'2018-08-10 15:00:00+05:30');

CREATE TABLE sell(
id int,
price int,
qty int,
in_status int,
dt_added_at timestamp
);

insert into sell values (1,15,20,1 ,'2018-08-10 12:00:00+05:30');
insert into sell values (2,12,15,1 ,'2018-08-10 13:00:00+05:30');
insert into sell values (3,10,15,1 ,'2018-08-10 14:00:00+05:30');
insert into sell values (4,10,20,1 ,'2018-08-10 15:00:00+05:30');
insert into sell values (5,10,15,1 ,'2018-08-10 16:00:00+05:30');
insert into sell values (6,10,20,1 ,'2018-08-10 17:00:00+05:30');





what about your 3 12 15 1 2018-08-10 14:00:00+05:30 this rows?
– Zaynul Abadin Tuhin
Aug 12 at 7:21





At a moment there is only one price matching between two tables so here I am only applying price is equal to 10.
– Khushang Bhavnagarwala.
Aug 12 at 7:23






Please refer the answer of d-shih below.
– Khushang Bhavnagarwala.
Aug 12 at 7:24





3 Answers
3



You can try to write a subquery with Row_number with window function to make row_number by price and qty, then you can get rn = 1 means the earlier
buy time by dt_added_at.


window function


price


qty


rn = 1


dt_added_at


CREATE TABLE Buy(
id int,
price int,
qty int,
in_status int,
dt_added_at timestamp
);


insert into Buy values (1,10,15,1,'2018-08-10 12:00:00+05:30');
insert into Buy values (2,10,20,1,'2018-08-10 13:00:00+05:30');
insert into Buy values (3,12,15,1,'2018-08-10 14:00:00+05:30');
insert into Buy values (4,15,20,1,'2018-08-10 15:00:00+05:30');

CREATE TABLE sell(
id int,
price int,
qty int,
in_status int,
dt_added_at timestamp
);


insert into sell values (1,15,20,1 ,'2018-08-10 12:00:00+05:30');
insert into sell values (2,12,15,1 ,'2018-08-10 13:00:00+05:30');
insert into sell values (3,10,15,1 ,'2018-08-10 14:00:00+05:30');
insert into sell values (4,10,20,1 ,'2018-08-10 15:00:00+05:30');
insert into sell values (5,10,15,1 ,'2018-08-10 16:00:00+05:30');



Query 1:


SELECT buy.*, s.*
FROM buy
LEFT JOIN (
select s.*,Row_number() over(PARTITION BY price,qty ORDER BY dt_added_at) rn
from sell s
) s ON
buy.price = s.price AND buy.qty = s.qty and rn = 1
WHERE
buy.price = 10
AND
buy.in_status = 1
AND
s.price = 10
AND
s.in_status = 1



Results:


| id | price | qty | in_status | dt_added_at | id | price | qty | in_status | dt_added_at | rn |
|----|-------|-----|-----------|----------------------|----|-------|-----|-----------|----------------------|----|
| 1 | 10 | 15 | 1 | 2018-08-10T12:00:00Z | 3 | 10 | 15 | 1 | 2018-08-10T14:00:00Z | 1 |
| 2 | 10 | 20 | 1 | 2018-08-10T13:00:00Z | 4 | 10 | 20 | 1 | 2018-08-10T15:00:00Z | 1 |





Let me try your solution. Hope it works.
– Khushang Bhavnagarwala.
Aug 12 at 7:19





I have added query in above question and found that there is an issue with a query. Can you please revise the query and look into it?
– Khushang Bhavnagarwala.
Aug 18 at 6:17





Can you please look into my issue again? Thanks.
– Khushang Bhavnagarwala.
Aug 18 at 7:03





@Khushang Bhavnagarwala. sorry reply so late I am busy in the morning and afternoon you can try to make row_number in buy table then get rn=1 sqlfiddle.com/#!17/5e205/14
– D-Shih
Aug 18 at 18:55



rn=1





@KhushangBhavnagarwala. Becasue you want to mapping rows which had been traded in first time.
– D-Shih
Aug 18 at 18:56



I would use a DISTINCT ON


DISTINCT ON


SELECT DISTINCT ON ( s.price, s.qty) b.*,
s.*
FROM buy b
LEFT JOIN sell s
ON b.price = s.price
AND b.qty = s.qty
WHERE b.price = 10
AND b.in_status = 1
AND s.price = 10
AND s.in_status = 1
ORDER BY s.price,
s.qty,
s.dt_added_at



Demo



Aggregate function min() help to you to pick FIFO based data


select t.*,s1.* from
(
select b.id,b.dt_added_at,
s.price,s.qty, min(s.dt_added_at) as sdt_added_at from
Buy b inner join
sell s on
b.price = s.price AND b.qty = s.qty
where s.in_status = 1 and b.price=10
group by s.price,s.qty,b.id,b.dt_added_at
) t
left join sell s1 on t.sdt_added_at =s1.dt_added_at



http://sqlfiddle.com/#!17/b543e3/9


id dt_added_at price qty sdt_added_at id price qty in_status dt_added_at
1 2018-08-10T12:00:00Z 10 15 2018-08-10T14:00:00Z 3 10 15 1 2018-08-10T14:00:00Z
2 2018-08-10T13:00:00Z 10 20 2018-08-10T15:00:00Z 4 10 20 1 2018-08-10T15:00:00Z






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

Creating a leaderboard in HTML/JS