gpt4 book ai didi

sql - 使用 Subselect 优化查询

转载 作者:行者123 更新时间:2023-12-03 16:54:17 28 4
gpt4 key购买 nike

我正在尝试生成一份销售报告,其中列出每个产品 + 给定月份的总销售额。这有点棘手,因为产品价格可能会在整个月内发生变化。例如:

  • 在 1 月 1 日和 1 月 15 日之间,我的公司以每个 10 美元的成本销售了 50 个小部件
  • 在 1 月 15 日和 1 月 31 日之间,我的公司以每个 15 美元的价格销售了 50 个以上的 Widget
  • 1 月份 Widget 的总销售额 = (50 * 10) + (50 * 15) = 1250 美元

此设置在数据库中表示如下:

Sales table  Sale_ID    ProductID    Sale_Date  1          1            2009-01-01  2          1            2009-01-01  3          1            2009-01-02             ...  50         1            2009-01-15  51         1            2009-01-16  52         1            2009-01-17             ...  100        1            2009-01-31Prices table  Product_ID    Sale_Date    Price  1             2009-01-01   10.00  1             2009-01-16   15.00

When a price is defined in the prices table, it is applied to all products sold with the given ProductID from the given SaleDate going forward.

Basically, I'm looking for a query which returns data as follows:

Desired output  Sale_ID    ProductID    Sale_Date     Price  1          1            2009-01-01    10.00  2          1            2009-01-01    10.00  3          1            2009-01-02    10.00             ...  50         1            2009-01-15    10.00  51         1            2009-01-16    15.00  52         1            2009-01-17    15.00             ...  100        1            2009-01-31    15.00

I have the following query:

SELECT
Sale_ID,
Product_ID,
Sale_Date,
(
SELECT TOP 1 Price
FROM Prices
WHERE
Prices.Product_ID = Sales.Product_ID
AND Prices.Sale_Date < Sales.Sale_Date
ORDER BY Prices.Sale_Date DESC
) as Price
FROM Sales

这可行,但是有比嵌套子选择更有效的查询吗?

在您指出在 Sales 表中包含“价格”会更容易之前,我应该提到该架构由另一个供应商维护,我无法更改它。以防万一,我使用的是 SQL Server 2000。

最佳答案

如果您开始存储开始日期和结束日期,或者创建一个包含开始日期和结束日期的 View (您甚至可以创建一个索引 View ),那么您可以大大简化您的查询。 (前提是你确定没有范围重叠)

SELECT
Sale_ID,
Product_ID,
Sale_Date,
Price
FROM Sales
JOIN Prices on Sale_date > StartDate and Sale_Date <= EndDate
-- careful not to use between it includes both ends

注意:

沿着这些思路的技术将允许您使用 View 来执行此操作。请注意,如果您需要为 View 编制索引,则必须花很多功夫......

create table t (d datetime)

insert t values(getdate())
insert t values(getdate()+1)
insert t values(getdate()+2)

go
create view myview
as
select start = isnull(max(t2.d), '1975-1-1'), finish = t1.d from t t1
left join t t2 on t1.d > t2.d
group by t1.d

select * from myview

start finish
----------------------- -----------------------
1975-01-01 00:00:00.000 2009-01-27 11:12:57.383
2009-01-27 11:12:57.383 2009-01-28 11:12:57.383
2009-01-28 11:12:57.383 2009-01-29 11:12:57.383

关于sql - 使用 Subselect 优化查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/481645/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com