简体   繁体   English

MYSQL - select 行基于条件,否则 select 其他行

[英]MYSQL - select row based on condition, otherwise select other row

I have a table products which have an association with product_prices .我有一个表productsproduct_prices有关联。 Each product can have multiple prices for different countries.每个产品在不同的国家可以有多个价格。

Desired outcome: When I run the query, I want to receive all products with 1 single price based on country condition .期望的结果:当我运行查询时,我想根据国家条件接收所有具有 1 个单一价格的产品

Logic逻辑

  1. If product has price for the specified country-> then country price will be displayed.如果产品有指定国家/地区的价格-> 则将显示国家/地区价格。
  2. If product does not have price for the specified country-> then price for with country_id 400 needs to be displayed.如果产品没有指定国家/地区的价格-> 则需要显示 country_id 400 的价格。
  3. 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.如果产品没有指定国家/地区和 ID 为 400 的国家/地区的价格 -> 则需要显示 country_id 为 500 的价格。
  4. 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.如果产品没有指定国家/地区和 id 400 的价格,而 id 500 -> 则显示具有最大用户总数的国家/地区的价格。

I did something like this for 1 single product.我为 1 个单一产品做了类似的事情。 But I don't know how to achieve these for all products.但我不知道如何为所有产品实现这些。

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;

My data: Country table我的数据:国家表

country_id国家代码 country_code国家代码 total_users总用户数
2 2个 FR FR 10 10
10 10 US我们 100 100
27 27 UK英国 200 200
400 400 EU欧盟 160 160
500 500 GLOBAL全球的 150 150

Product price table产品价格表

product_id产品编号 price_id价格编号 price价格 country_id国家代码
product1产品1 1a 1a 19.99 19.99 27 27
product1产品1 1b 1b 20.99 20.99 400 400
product1产品1 1c 1c 30.99 30.99 500 500
product2产品2 2a 2a 199.99 199.99 10 10
product2产品2 2b 2b 299.99 299.99 400 400
product3产品3 3a 3a 50.99 50.99 500 500
product4产品4 4a 4a 40 40 2 2个
product4产品4 4a 4a 45 45 10 10

My expected output when inserting country 27:插入国家/地区 27 时我预期的 output:

product_id产品编号 price价格 country_id国家代码
product1产品1 19.99 19.99 27 27
product2产品2 20.99 20.99 400 400
product3产品3 50.99 50.99 500 500
product4产品4 45 45 10 10

I did something like this.我做了这样的事情。 But I am not sure only about the last part.但我不确定只有最后一部分。 In case product price needs to be choosed based on total dealers.如果需要根据总经销商来选择产品价格。

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;

With MySQL 8.0+ ROW_NUMBER() allows to drop all rows except first per product:使用 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 https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=94f8851be7f309d8c4fd1946230d7999

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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