SQL 服务器:此查询出现表达式错误

SQL Server: get expression error with this query

Table:

create table produts_1164 
(
    product_id int,
    new_price int,
    change_date date
);

insert into produts_1164 
values (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');

问题:写一个SQL查询来查找2019-08-16所有产品的价格。假设所有产品在任何变化之前的价格都是 10。

这是我的解决方案:

select product_id, new_price as price 
from products
where (product_id, change_date) in (select product_id, max(change_date) 
                                    from products 
                                    where change_date <= '2019-08-16' 
                                    group by product_id)
union
select product_id, 10 as price 
from products
where product_id not in (select distinct product_id 
                         from products 
                         where change_date <= '2019-08-16');

但是我得到这个错误:

[42000] [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]An expression of non-boolean type specified in a context where a condition is expected, near ','. (4145) (SQLExecDirectW)

知道这个吗?谢谢

一种方法是相关子查询:

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

或window函数:

select p.*
from (select p.*,
             row_number() over (partition by product_id order by change_date desc) as seqnum
      from produts_1164 p
      where p.change_date <= '2019-08-16'
     ) p
where seqnum = 1;

如果您想要 所有 产品在给定时间点的价格,包括那些在该日期之前没有变化的产品(默认值为 20),您需要查看所有行(不仅是目标日期之前的行)。

我会在这里使用 outer apply

select p.product_id, coalesce(p1.new_price, 20), p1.change_date
from (select distinct product_id from produts_1164) p
outer apply (
    select top 1 * 
    from produts_1164 p1 
    where p1.product_id = p.product_id and p1.change_date <= '2019-08-16'
    order by p1.change_date desc
) p1

Demo on DB Fiddle:

product_id | (No column name) | change_date
---------: | ---------------: | :----------
         1 |               35 | 2019-08-16 
         2 |               50 | 2019-08-14 
         3 |               20 | null