skip to Main Content

I want to retrieve all buy orders with a count of matching buy orders in a single query.
A match would be a sell order that satisfies all attributes (greater or equal) and is cheaper than the buy order. Is that even possible?

This is my table structure:

Attributes

id name
1 Area (m2)
2 Rooms

Sell Orders

id title price
1 Flat #1 500.000,00€
2 House #1 1.000.000,00€
…. ….

Sell Order Attributes

sell_order_id attribute_id value
1 1 90
1 2 3
2 1 239
2 2 5

Buy Orders

id offer
1 600.000,00€
2 150.000,00€

Buy Order Attributes

buy_order_id attribute_id value
1 1 80
1 2 2
2 1 200
2 2 3

I tried solving it in MySQL Workbench but I could not figure it out

2

Answers


  1. I assume that the sell order id and buy order id is related. If not, then there is no relations in your data between sell and buy tables. You can try something like below to get the raw answer. First cte creates marker for all attributes. Second CTE gets all sales ids that fulfil all the attribute needs. Then final select gets the cases where buy orders are in line with sales attribute needs and price less than the buy order.

       with cte as ( 
    select s.*
    case
            when a.[attribute_id] = 'whatever attribute you choose' and a.value >= 'whatever the benchmark is' then 1
            when a.[attribute_id] = 'whatever 2nd attribute you choose' and a.value >= 'whatever the benchmark is' then 1
                else 0
                end as marker
        from [Sell Orders]  s
            inner join [Sell Order Attributes] a on s.id = a.sell_order_id
    ),
    
    cte2 as (
    select id , sum(marker)
    from cte
    group by id
    having sum(marker) = 2 --however many attributes you are testing
    )
    
    select *
        from [Buy Orders] b on b.id = s.id
            inner join [Buy Order Attributes] c on b.id = c.buy_order_id
            inner join  cte2 t on t.id = b.id
    
    
            Where  t.price < b.price
    
    Login or Signup to reply.
  2. As you don’t store price and offer as decimal or other numeric types you need always to cast it, which will take some time, besides monetary datatypes arent’t supported, so you should redesign your tables.

    the rest is a lot of joins with the correct ON clause.

    It will compare the price against the offer and all attributes that match

    SELECT DISTINCT s.*,b.*
    FROM Sell_Orders s JOIN Sell_Order_Attributes sa ON sa.`sell_order_id` = s.`id`
    JOIN Buy_Orders b ON CAST( REPLACE(REPLACE(REPLACE(b.`offer`,'€',''),'.',''),',','.') AS DECIMAL(20,2))  >= CAST( REPLACE(REPLACE(REPLACE(s.price,'€',''),'.',''),',','.') AS DECIMAL(20,2))  JOIN Buy_Order_Attributes ba ON ba.`buy_order_id` = b.`id` 
      and ba.`attribute_id` = sa.`attribute_id`and sa.`value` >= ba.`value`
    
    
    id title price id offer
    1 Flat #1 500.000,00€ 1 600.000,00€

    fiddle

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search