我有两张桌子。一个ID及其价格表和第二个每个ID折扣表。在折扣表中,一个Id可以有很多折扣,我需要知道一个Id的最终价格。
查询它的最佳方式是什么(在一次查询中)?对于每个id的许多折扣,查询应该是通用的(不仅仅是下面示例中提到的2个)
例如表1
id price
1 2.00
2 2.00
3 2.00
表二
id Discount
1 0.20
1 0.30
2 0.40
3 0.50
3 0.60
最终结果:
id OrigPrice PriceAfterDiscount
1 2.00 1.12
2 2.00 1.20
3 2.00 0.40
下面是另一种方法:
SELECT T1.ID, T1.Price, T1.Price * EXP(SUM(LOG(1 - T2.Discount)))
FROM T1 INNER JOIN T2 ON T1.ID = T2.ID
GROUP BY T1.ID, T1.Price
exp/log技巧只是做乘法的另一种方法。
如果您在T1中有条目,而在T2中没有折扣,那么您可以将INNER JOIN更改为LEFT JOIN。您将得到以下结果:
ID Price Discount
4 2.00 NULL
您的逻辑可以考虑折扣价格列中的空值并取而代之的是原始价格,或者只是为这些值添加一个0折扣记录。
通常,它可以通过log/exp
函数的技巧来完成,但它很复杂。下面是一个基本示例:
declare @p table(id int, price money)
declare @d table(id int, discount money)
insert into @p values
(1, 2),
(2, 2),
(3, 2)
insert into @d values
(1, 0.2),
(1, 0.3),
(2, 0.4),
(3, 0.5),
(3, 0.6)
select p.id,
p.price,
p.price * ca.discount as PriceAfterDiscount
from @p p
cross apply (select EXP(SUM(LOG(1 - discount))) as discount FROM @d where id = p.id) ca
对于更简单的(基于光标的方法),您将需要一个递归的CTE
,但在这种情况下,您需要discounts
表中的某个唯一的排序列才能正确运行它。这在@Tanner`的回答中显示了出来。
最后,您可以使用常规光标进行处理