简体   繁体   English

在 WHERE 子句中使用 CASE

[英]Using CASE in WHERE clause

I have 2 tables that needs to be joined based on couple of parameters.我有 2 个表需要根据几个参数进行连接。 One of the parameters is year.其中一个参数是年份。 One table contains the current year but another year doesn't contain current year, so it must use the latest year and matched with other parameters.一个表包含当前年份,而另一年份不包含当前年份,因此必须使用最近的年份并与其他参数匹配。

Example例子

Product产品

-------------------------------------------------------------------------------
| product_id | category_id | sub_category_id | product_year | amount |
-------------------------------------------------------------------------------
| 504        | I           | U               | 2020         | 400    |
| 510        | I           | U               | 2019         | 100    |
| 528        | I           | U               | 2019         | 150    |
| 540        | I           | U               | 2018         | 1000   |

Discount折扣

-----------------------------------------------------------------------------
| discount_year | category_id | sub_category_id | discount |
-----------------------------------------------------------------------------
| 2018          | I           | U               | 0.15     |
| 2017          | I           | U               | 0.35     |
| 2016          | I           | U               | 0.50     |

Output输出

-----------------------------------------------------------------------------
| product_id | category_id | sub_category_id | product_year | discount_year |
-----------------------------------------------------------------------------
| 504        | I           | U               | 2020         | 2018          |
| 510        | I           | U               | 2019         | 2018          |
| 528        | I           | U               | 2019         | 2018          |
| 540        | I           | U               | 2018         | 2017          |

The discount is always gotten from one year behind but if those rates aren't available, then it would keep going back a year until available.折扣总是从一年后获得,但如果这些费率不可用,那么它会一直回溯一年直到可用。

I have tried the following:我尝试了以下方法:

SELECT 
    product_year, a.product_id, a.category_id, a.sub_category_id, 
    discount_year, amount, discount
FROM
    Product a
INNER JOIN 
    Discount b ON a.category_id = b.category_id 
               AND a.sub_category_id  = b.sub_category_id
               AND product_ year = CASE
                                      WHEN discount_year + 1 = product_year 
                                         THEN discount_year + 1
                                      WHEN discount_year + 2 = product_year 
                                         THEN discount_year + 2
                                      WHEN discount_year + 3 = product_year 
                                         THEN discount_year + 3
                                   END
 WHERE 
     product = 540

This return the following output:这将返回以下输出:

--------------------------------------------------------------------------------------------------
| product_year | product_id | category_id | sub_category_id | discount_year | amount | discount |
--------------------------------------------------------------------------------------------------
| 2016         | 540        | I           | U               | 2017          | 1000   | 0.50     |
| 2017         | 540        | I           | U               | 2017          | 1000   | 0.35     |

Any help will be appreciated.任何帮助将不胜感激。

You can use OUTER APPLY and a subquery.您可以使用OUTER APPLY和子查询。 In the subquery select the row with the maximum discount_year , that is less the product_year using TOP and ORDER BY .在子查询中,使用TOPORDER BY选择具有最大discount_year的行,即小于product_year

SELECT p.product_year,
       p.product_id,
       p.category_id,
       p.sub_category_id,
       d.discount_year,
       p.amount,
       d.discount
       FROM product p
            OUTER APPLY (SELECT TOP 1
                                *
                                FROM discount d
                                WHERE d.category_id = p.category_id
                                      AND d.sub_category_id = p.sub_category_id
                                      AND d.discount_year < p.product_year
                                ORDER BY d.discount_year DESC) d;

您可以使用子查询代替 CASE 表达式来选择小于您的product_year的 TOP 1 相关discount_year ,ORDER BY discount_year ASC。

Create a product to discount mapping using a CTE first.首先使用 CTE 创建产品折扣映射。 This contains the discount year pulled from discount table for every product year in the product table and corresponding product_id.这包含从产品表中每个产品年份的折扣表中提取的折扣年份和相应的 product_id。 Following this, you can easily join with relevant tables to get results and eliminate any nulls as needed在此之后,您可以轻松地加入相关表以获得结果并根据需要消除任何空值

Simplified query.简化的查询。

 ;WITH disc_prod_mapper 
    AS
    (
    SELECT  product_id, product_year,(SELECT MAX(discount_year) FROM  #Discount b WHERE discount_year < product_year AND a.category_id  = b.category_id  AND a.sub_category_id   = b.sub_category_id ) AS discount_year
     FROM Product a  
    )
    SELECT a.product_year, c.discount_year, a.amount, c.discount
    FROM Product a
      LEFT JOIN disc_prod_mapper b   ON a.product_id  = b.product_id   
      LEFT JOIN Discount c ON b.discount_year = c.discount_year

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

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