Sql 从联接表获取特定行时交叉应用的替代方法?
我有两张表:OrderItem和SkuPrice 正如您可能猜到的,OrderItem保存订单上的SKU项的详细信息。OrderItem表中每个订单的每个SKU都有一个条目 SkuPrice保存SKU的价格。每个SKU可以有多个条目。每个条目都有一个effectivefromtc值,即价格生效的日期和时间,有些条目还可能有一个EffectiveToUtc值,表示价格是暂时的,这用于临时降价。SkuPrice还有一个标志IsCostPrice,告诉我们条目是成本价还是零售价 我在查询中加入了这些表和订单表,以确定OrderItem表中每个SKU的完整价格、降价价格(如果有)和成本价格。我已经使用外部应用和交叉应用来实现我需要的结果。。。但是查询效率很低,请参见下文 我觉得我应该用不同的方式来做。有没有更好的办法 请注意,“完整价格”是没有生效日期的最新价格。成本价格相同,但IsCostPrice标志必须为真Sql 从联接表获取特定行时交叉应用的替代方法?,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有两张表:OrderItem和SkuPrice 正如您可能猜到的,OrderItem保存订单上的SKU项的详细信息。OrderItem表中每个订单的每个SKU都有一个条目 SkuPrice保存SKU的价格。每个SKU可以有多个条目。每个条目都有一个effectivefromtc值,即价格生效的日期和时间,有些条目还可能有一个EffectiveToUtc值,表示价格是暂时的,这用于临时降价。SkuPrice还有一个标志IsCostPrice,告诉我们条目是成本价还是零售价 我在查询中加入了这些表
嗯,我想你的交叉应用可能会被修改为exists子句,因为你没有在select或where子句中使用它们。您的外部应用程序可以是一个左连接所有应用程序都可以重新编写为一个连接,尽管有时它们会因此看起来更难看,但这可能不会对查询的性能产生太大影响。编辑:如果您遇到性能问题,我建议您仔细查看执行计划,找出是什么让您慢下来,以及适当的索引是否可以改善这一点。在这种情况下,我认为没有理由使用交叉或外部应用。应用通常在调用需要传入参数的用户定义函数时使用。我会使用1个或多个CTE编写此查询,而不是使用apply。我最终做了两件事:创建第二个价格表,为每个SKU保存非规范化的价格数据,当价格元素发生变化时,每个时间点都有一条记录。b使用CTEs构造查询
SELECT CustomerOrder.Id AS OrderId, CustomerOrder.DatePlacedUtc, OrderItem.Id As OrderItem, OrderItem.Sku,
TempPrice.Value AS TempPrice,
OrderItem.ItemRetailPrice
FROM [dbo].[Order] CustomerOrder JOIN OrderItem ON CustomerOrder.Id = OrderItem.OrderId
OUTER APPLY
(
SELECT Sku, Value, NetValue, VatRate
FROM SkuPrice (NOLOCK)
WHERE IsCostPrice = 0
AND EffectiveFromUtc <= CustomerOrder.DatePlacedUtc
AND EffectiveToUtc > CustomerOrder.DatePlacedUtc
AND Sku = OrderItem.Sku
) TempPrice
CROSS APPLY
(
SELECT TOP 1 Sku, Value, NetValue, VatRate
FROM SkuPrice (NOLOCK)
WHERE IsCostPrice = 0
AND Sku = OrderItem.Sku
AND EffectiveFromUtc <= CustomerOrder.DatePlacedUtc
AND EffectiveToUtc IS NULL
ORDER BY EffectiveFromUtc DESC
) FullPrice
CROSS APPLY
(
SELECT TOP 1 Sku, Value, NetValue, VatRate
FROM SkuPrice (NOLOCK)
WHERE IsCostPrice = 1
AND Sku = OrderItem.Sku
AND EffectiveFromUtc <= CustomerOrder.DatePlacedUtc
AND EffectiveToUtc IS NULL
ORDER BY EffectiveFromUtc DESC
) CostPrice
WHERE CustomerOrder.OrderStatusId >= 20 AND CustomerOrder.OrderStatusId < 200
ORDER BY CustomerOrder.Id ASC, OrderItem.Sku ASC