开发者

MYSQL - Conditional Column (if row exists) otherwise default to first returned

开发者 https://www.devze.com 2023-04-11 19:46 出处:网络
I am certain this is non-conventional, howeve开发者_如何学JAVAr I am trying to perform the following:

I am certain this is non-conventional, howeve开发者_如何学JAVAr I am trying to perform the following:

I have the following Table:

products_id, company_id, products_name
1,           1,          shoes
1,           2,          mens shoes
2,           1,          pants

Now, what I want to do is select a particular products_name from this using a given products_id and company_id = '2', however in all cases where it does not find a row with company_id = '2' I want it to default to giving me the products_name for the same product_id with ANY company_id.

For instance, if I were to search for products_id = '2', company_id = '2' it should return products_name = 'pants'. However, if I were to search products_id = '1', company_id = '2' it should return 'mens shoes'. If I were to search products_id = '3', company_id = anything - it should return an empty set.

I need to be able to do this in a single SQL statement, so no handling via PHP to confirm whether or not a row exists with say: products_id = '2' company_id = '2'.

The actual application uses a far more complex table with multiple joins, however it's this simple bit that I cannot figure out, so if anyone could help me with this hurdle it would be much appreciated.


Here is a query that will return the company's product, or any generic one if there isn't a specific product for that company, across the entire product list. It can easily be filtered with an extra where products_id = ## at the end (or by putting a where filter inside the two inner sub-queries which might actually be more efficient):

set @company_id = 2;

select
    coalesce(p2.products_id, p1.products_id) as products_id,
    coalesce(p2.products_name, p1.products_name) as products_name
from
    (select products_id, max(products_name) as products_name
        from products group by products_id) p1
left join
    (select products_id, products_name
        from products where company_id = @company_id) p2
    on p1.products_id = p2.products_id

Demo: http://sqlize.com/pkt568O0b5

The basic idea behind my logic was this:

  1. Create a query that pulls in an arbitrary product name per product id - by just pulling the max of product name and grouping by id.
  2. Create a query that pulls the product name for the company being filtered for.
  3. Left join #2 with #1, so that I will have a list of products, plus the product name for the company if it is available. Because of the left join, all the products will still be returned, but for the products that don't have a specific name for the given company, the company-specific list will be NULL.
  4. Select the product id and name from the given company-specific list, if available. If not available, then use the generic list which just pulls max of product name. This is handled through the coalesce function, which returns the first non-null argument in its list. So basically it checks the company-specific list first, and if nothing is available, uses the generic list instead.

Hope this helps!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号