简体   繁体   中英

How to join table with condition on row values?

Below are my table data

Table A

| amount | range   | id  |
+--------+---------+-----+
|    720 |       1 | 115 |
|    360 |       2 | 115 |
|    180 |       3 | 115 |
|    180 |       4 | 115 |
|    135 |       5 | 115 |
|    135 |      10 | 115 |

Table B

+------+-----+
| rank | a_id|
+------+-----+
|    1 | 115 |
|    2 | 115 |
|    3 | 115 |
|    4 | 115 |
|    5 | 115 |
|    6 | 115 |
|    7 | 115 |
|    8 | 115 |
|    9 | 115 |
|   10 | 115 |

I need to get the following result by joining these two tables.

+------+-----+--------+
| rank | a_id| amount |
+------+-----+--------+
|    1 | 115 |720
|    2 | 115 |360
|    3 | 115 |180
|    4 | 115 |180
|    5 | 115 |135
|    6 | 115 |135
|    7 | 115 |135
|    8 | 115 |135
|    9 | 115 |135
|   10 | 115 |135

Since I have tried with the below query. But I am unable to get the exact result. since its only matching with the rank. I have tried the queries with case also but I didn't get the exact result. Any suggestions for how to solve it

select rank
     , sample_test.amount 
  from a 
  join b 
    on a.id = b.a_id 
    and rank = range 
 order 
    by rank

Join the tables and group by rank, a_id to get the min amount of each group:

select
  b.rank, b.a_id, min(a.amount) amount
from tableb b inner join tablea a
on b.a_id = a.id and b.rank >= a.range
group by b.rank, b.a_id

See the demo .
Depending on the intervals and the ranks, maybe the logic (which is not clear enough) could be to use the opposite sign in the ON clause and max instead of min:

select
  b.rank, b.a_id, max(a.amount) amount
from tableb b inner join tablea a
on b.a_id = a.id and b.rank <= a.range
group by b.rank, b.a_id

See the demo .
Both queries (for this sample data) return the same results:

| rank | a_id | amount |
| ---- | ---- | ------ |
| 1    | 115  | 720    |
| 2    | 115  | 360    |
| 3    | 115  | 180    |
| 4    | 115  | 180    |
| 5    | 115  | 135    |
| 6    | 115  | 135    |
| 7    | 115  | 135    |
| 8    | 115  | 135    |
| 9    | 115  | 135    |
| 10   | 115  | 135    |

You can try this simple sub query option-

SELECT *,
(
    SELECT TOP 1 amount 
    FROM TableA A 
    WHERE A.range <=  B.rank
    AND A.id = B.a_id
    ORDER BY A.range DESC
) Amount 
FROM TableB B

You can check DEMO HERE

In MySQL, I would use a correlated subquery:

SELECT b.*,
       (SELECT a.amount 
        FROM TableA a
        WHERE a.range <= b.rank AND
              a.id = b.a_id
        ORDER BY a.range DESC
       ) as Amount 
FROM TableB b;

In particular, this can take advantage of an index on TableA(id, range desc) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM