MYSQL - select 行基于条件,否则 select 其他行
MYSQL - select row based on condition, otherwise select other row
我有一个 table 产品,它与 product_prices 有关联。
每个产品在不同国家可以有多个价格。
期望的结果:当我运行查询时,我想收到所有基于国家条件[=46]的单一价格的所有产品=].
Logic
- If product has price for the specified country-> then country price
will be displayed.
- If product does not have price for the specified
country-> then price for with country_id 400 needs to be displayed.
- If product has no price for specified country and for country with id 400 -> then the price with country_id 500 needs to be displayed.
- If product has not price for specified country and id 400, and id 500 -> then price which has country with biggest amount of total users will be
displayed.
我为 1 个单一产品做了类似的事情。但我不知道如何为所有产品实现这些。
select p.id, pp.price, pp.country_id,
(CASE WHEN (pp.country_id=:countryId) then 0 else
(CASE WHEN (pp.country_id=400) then 1 else
(case when (pp.country_id=500) then 2 else 3 END) END) END) as priorityIndex
from products p
inner join product_prices pp on p.id = pp.product_id
inner join countries c on pp.country_id = c.id
where p.id = '00057c218b154d5b838b928a0189ff9f'
order by priorityIndex limit 1;
我的数据:
国家/地区 table
country_id
country_code
total_users
2
FR
10
10
US
100
27
UK
200
400
EU
160
500
GLOBAL
150
产品价格table
product_id
price_id
price
country_id
product1
1a
19.99
27
product1
1b
20.99
400
product1
1c
30.99
500
product2
2a
199.99
10
product2
2b
299.99
400
product3
3a
50.99
500
product4
4a
40
2
product4
4a
45
10
插入国家/地区 27 时我的预期输出:
product_id
price
country_id
product1
19.99
27
product2
20.99
400
product3
50.99
500
product4
45
10
我做了这样的事情。但我不确定只有最后一部分。如果需要根据经销商总数选择产品价格。
select A.id, A.price_id, A.price, A.country from
(select p.id, pp.id as price_id, pp.price, pp.country_id as country,
ROW_NUMBER() over (PARTITION BY p.id order by (CASE WHEN (pp.country_id=:countryId) then 0 else
(CASE WHEN (pp.country_id=400) then 1 else
(case when (pp.country_id=500) then 2 else 3 END) END) END), c.total_dealer_users desc) AS rowNumber
from products p
inner join product_prices pp on p.id = pp.product_id
inner join countries c on pp.country_id = c.id
where p.id in ('00057c218b154d5b838b928a0189ff9f','054a8caf911e4ff3a594990af20a9611')) as A
where rowNumber=1;
使用 MySQL 8.0+ ROW_NUMBER()
允许删除每个产品的第一行除外的所有行:
SELECT * FROM (
SELECT p.id,
pp.price,
pp.country_id,
ROW_NUMBER() OVER (PARTITION BY p.id ORDER BY FIELD(pp.country_id, 500, 400, 27) DESC) AS `rn`
FROM products AS p
JOIN product_prices AS pp
ON p.id = pp.product_id
WHERE p.id IN (...)
) AS t WHERE t.rn=1
SELECT
*
FROM
(
SELECT
pp.product_id,
pp.price_id,
pp.price,
pp.country_id as country,
ROW_NUMBER() OVER (
PARTITION BY pp.product_id
ORDER BY FIELD(
c.country_id,
27,
400,
500,
c.country_id
),
c.total_users DESC
)
AS rowNumber
FROM
product_price pp
INNER JOIN
country c
ON pp.country_id = c.country_id
)
AS ranked_price
WHERE
rowNumber=1;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=94f8851be7f309d8c4fd1946230d7999
我有一个 table 产品,它与 product_prices 有关联。 每个产品在不同国家可以有多个价格。
期望的结果:当我运行查询时,我想收到所有基于国家条件[=46]的单一价格的所有产品=].
Logic
- If product has price for the specified country-> then country price will be displayed.
- If product does not have price for the specified country-> then price for with country_id 400 needs to be displayed.
- If product has no price for specified country and for country with id 400 -> then the price with country_id 500 needs to be displayed.
- If product has not price for specified country and id 400, and id 500 -> then price which has country with biggest amount of total users will be displayed.
我为 1 个单一产品做了类似的事情。但我不知道如何为所有产品实现这些。
select p.id, pp.price, pp.country_id,
(CASE WHEN (pp.country_id=:countryId) then 0 else
(CASE WHEN (pp.country_id=400) then 1 else
(case when (pp.country_id=500) then 2 else 3 END) END) END) as priorityIndex
from products p
inner join product_prices pp on p.id = pp.product_id
inner join countries c on pp.country_id = c.id
where p.id = '00057c218b154d5b838b928a0189ff9f'
order by priorityIndex limit 1;
我的数据: 国家/地区 table
country_id | country_code | total_users |
---|---|---|
2 | FR | 10 |
10 | US | 100 |
27 | UK | 200 |
400 | EU | 160 |
500 | GLOBAL | 150 |
产品价格table
product_id | price_id | price | country_id |
---|---|---|---|
product1 | 1a | 19.99 | 27 |
product1 | 1b | 20.99 | 400 |
product1 | 1c | 30.99 | 500 |
product2 | 2a | 199.99 | 10 |
product2 | 2b | 299.99 | 400 |
product3 | 3a | 50.99 | 500 |
product4 | 4a | 40 | 2 |
product4 | 4a | 45 | 10 |
插入国家/地区 27 时我的预期输出:
product_id | price | country_id |
---|---|---|
product1 | 19.99 | 27 |
product2 | 20.99 | 400 |
product3 | 50.99 | 500 |
product4 | 45 | 10 |
我做了这样的事情。但我不确定只有最后一部分。如果需要根据经销商总数选择产品价格。
select A.id, A.price_id, A.price, A.country from
(select p.id, pp.id as price_id, pp.price, pp.country_id as country,
ROW_NUMBER() over (PARTITION BY p.id order by (CASE WHEN (pp.country_id=:countryId) then 0 else
(CASE WHEN (pp.country_id=400) then 1 else
(case when (pp.country_id=500) then 2 else 3 END) END) END), c.total_dealer_users desc) AS rowNumber
from products p
inner join product_prices pp on p.id = pp.product_id
inner join countries c on pp.country_id = c.id
where p.id in ('00057c218b154d5b838b928a0189ff9f','054a8caf911e4ff3a594990af20a9611')) as A
where rowNumber=1;
使用 MySQL 8.0+ ROW_NUMBER()
允许删除每个产品的第一行除外的所有行:
SELECT * FROM (
SELECT p.id,
pp.price,
pp.country_id,
ROW_NUMBER() OVER (PARTITION BY p.id ORDER BY FIELD(pp.country_id, 500, 400, 27) DESC) AS `rn`
FROM products AS p
JOIN product_prices AS pp
ON p.id = pp.product_id
WHERE p.id IN (...)
) AS t WHERE t.rn=1
SELECT
*
FROM
(
SELECT
pp.product_id,
pp.price_id,
pp.price,
pp.country_id as country,
ROW_NUMBER() OVER (
PARTITION BY pp.product_id
ORDER BY FIELD(
c.country_id,
27,
400,
500,
c.country_id
),
c.total_users DESC
)
AS rowNumber
FROM
product_price pp
INNER JOIN
country c
ON pp.country_id = c.country_id
)
AS ranked_price
WHERE
rowNumber=1;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=94f8851be7f309d8c4fd1946230d7999