【问题标题】:Query to find the prices of all products on 2019-08-16查询2019-08-16所有产品的价格
【发布时间】:2021-04-12 14:47:24
【问题描述】:

我正在做以下练习:

问题 67
表:产品

 +---------------+---------+
 | Column Name   | Type    |
 +---------------+---------+
 | product_id    | int     |
 | new_price     | int     |
 | change_date   | date    |
 +---------------+---------+

(product_id, change_date) 是该表的主键。 此表的每一行都表示某些产品的价格在某个日期更改为新价格。 编写 SQL 查询,查找 2019 年 8 月 16 日所有产品的价格。假设所有产品在任何变化之前的价格都是 10。 查询结果格式如下例: 产品表:

 +------------+-----------+-------------+
 | product_id | new_price | change_date |
 +------------+-----------+-------------+
 | 1          | 20        | 2019-08-14  |
 | 2          | 50        | 2019-08-14  |
 | 1          | 30        | 2019-08-15  |
 | 1          | 35        | 2019-08-16  |
 | 2          | 65        | 2019-08-17  |
 | 3          | 20        | 2019-08-18  |
 +------------+-----------+-------------+

结果表:

 +------------+-------+
 | product_id | price |
 +------------+-------+
 | 2          | 50    |
 | 1          | 35    |
 | 3          | 10    |
 +------------+-------+

这是其他人给出的解决方案:

-- Solution
with t1 as (
select a.product_id, new_price
from(
Select product_id, max(change_date) as date
from products
where change_date<='2019-08-16'
group by product_id) a
join products p
on a.product_id = p.product_id and a.date = p.change_date),

t2 as (
select distinct product_id
    from products)
    
select t2.product_id, coalesce(new_price,10) as price
from t2 left join t1
on t2.product_id = t1.product_id
order by price desc

这是我的解决方案。我试图在互联网上找到其他解决方案,但它们都是以非常复杂的方式,为什么没有人这样做。如果我的解决方案有什么问题,请告诉我?

SELECT
     t.product_id
    ,CASE
         WHEN t.change_date <= '2019-08-16' THEN t.new_price 
         ELSE 10
     END AS price
FROM 
(
    SELECT
         product_id
        ,new_price
        ,change_date
        ,RANK() OVER
         (
             PARTITION BY product_id 
             ORDER BY change_date DESC) AS rk 
    FROM products
) t
WHERE t.rk = 1

【问题讨论】:

  • 可能是性能问题!有时 Windows 功能在某些情况下会受到影响

标签: sql sql-server tsql


【解决方案1】:

您的解决方案如下(我让 SQLPrompt 对其进行格式化以提高可读性)。您的解决方案有效。并且运作良好。我经常使用完全相同的技术。我建议使用 ROW_NUMBER() 而不是 RANK() 因为总是有可能获得 2 个相同的行——至少它发生在我身上足以让我改变。但是您的原始解决方案效果很好。

SELECT t.product_id
     , CASE
           WHEN t.change_date <= '2019-08-16' THEN
               t.new_price
           ELSE
               10
       END AS price
FROM
(
    SELECT product_id
         , new_price
         , change_date
         , ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY change_date DESC) AS rk
    FROM products
) t
WHERE t.rk = 1;

【讨论】:

    【解决方案2】:

    您可以使用相关子查询:

    select p.*
    from products p
    where p.date = (select max(p2.date)
                    from products p2
                    where p2.product_id = p.product_id and
                          p2.date <= '2019-08-16'
                   );
    

    【讨论】:

      猜你喜欢
      • 2022-06-22
      • 1970-01-01
      • 1970-01-01
      • 2011-03-28
      • 2019-10-29
      • 2020-05-16
      • 1970-01-01
      • 2019-07-09
      • 1970-01-01
      相关资源
      最近更新 更多