我有两个表FactLik
(200万行)和UpdateStPrice
(500k行)。
我需要使用规则更新FactLik
表。
| PRODUCTKEY | WAREHOUSEKEY | STARTDATE | ENDDATE | PRIORITY | UNITPRICE |
---------------------------------------------------------------------------
| 36975 | 6 | 20120630 | 20121011 | 0 | 395 |
| 36975 | 6 | 20121018 | 20291231 | 0 | 371 |
| 36975 | 6 | 20121126 | 20121211 | 120 | 313 |
| 36975 | 6 | 20121126 | 20121219 | 120 | 288 |
| 36975 | 6 | 20121212 | 20291231 | 120 | 313 |
| TIMEKEY | PRODUCTKEY | PRODUCTGROUPKEY | WAREHOUSEKEY | PRICE |
-------------------------------------------------------------------
| 20121205 | 36975 | 89 | 6 | (null) |
ProductKey
,WarehouseKey
在UpdateStPrice
行中找到Priority
为MAX且FactLik.TimeKey
介于StartDate
和{{1}之间的行}。EndDate
为MAX的行。StartDate
为MIN的行。 来自EndDate
的预期结果:
UpdateStPrice
结果| PRODUCTKEY | WAREHOUSEKEY | STARTDATE | ENDDATE | PRIORITY | UNITPRICE |
---------------------------------------------------------------------------
| 36975 | 6 | 20121126 | 20121211 | 120 | 313 |
:
FactLik
我My QUERY非常慢,实际上她的跑步速度超过12小时。我在两个表上都有一些索引(建议执行计划),但他们根本没有帮助:)
所以,如果你能帮助我优化这个查询,我将非常感激。
答案 0 :(得分:3)
我认为你可以通过从UpdateStPrice订购数据来实现这一目的:
UPDATE factlik
SET price =
(SELECT TOP 1 up.unitprice
FROM updatestprice up
WHERE up.productkey = factlik.productkey
AND up.warehousekey = factlik.warehousekey
AND factlik.timekey >= up.startdate
AND factlik.timekey <= up.enddate
ORDER BY priority desc, startdate desc, enddate
)
sqlfiddle here
答案 1 :(得分:0)
这似乎是针对窗口函数量身定制的,在子查询表中引用:
UPDATE factlik SET price = up.unitprice
FROM factlik
JOIN (SELECT factlik.timekey, factlik.productkey, factlik.warehousekey,
up.unitprice,
ROW_NUMBER() OVER(ORDER BY up.priority DESC,
up.startdate DESC,
up.enddate ASC) as rownum
FROM updatestprice up
JOIN factlik
ON up.productkey = factlik.productkey
AND up.warehousekey = factlik.warehousekey
AND up.startdate <= factlik.timekey
AND up.enddate > factlik.timekey) up
ON up.timekey = factlik.timekey
AND up.productkey = factlik.productkey
AND up.warehousekey = factlik.warehousekey
AND up.rownum = 1
答案 2 :(得分:0)
这应该有效:
UPDATE factlik
SET price =
(SELECT
unitprice
FROM
updatestprice u INNER JOIN
(SELECT
ms.productkey,
ms.warehousekey,
max_priority,
max_start,
MIN(enddate) AS min_end
FROM
updatestprice u INNER JOIN
factlik f ON
u.productkey = f.productkey AND
u.warehousekey = f.warehousekey AND
timekey >= startdate AND
timekey <= EndDate INNER JOIN
(SELECT
mp.productkey,
mp.warehousekey,
max_priority,
MAX(startdate) AS max_start
FROM
updatestprice u INNER JOIN
factlik f ON
u.productkey = f.productkey AND
u.warehousekey = f.warehousekey AND
timekey >= startdate AND
timekey <= EndDate INNER JOIN
(SELECT
u.productkey,
u.warehousekey,
MAX([priority]) AS max_priority
FROM
updatestprice u INNER JOIN
factlik f ON
u.productkey = f.productkey AND
u.warehousekey = f.warehousekey AND
timekey >= startdate AND
timekey <= EndDate
GROUP BY
u.productkey,
u.warehousekey ) mp ON
u.productkey = mp.productkey AND
u.warehousekey = mp.warehousekey AND
u.priority = mp.max_priority
GROUP BY
mp.productkey,
mp.warehousekey,
max_priority
) ms ON
u.productkey = ms.productkey AND
u.warehousekey = ms.warehousekey AND
u.priority = ms.max_priority AND
u.startdate = ms.max_start
GROUP BY
ms.productkey,
ms.warehousekey,
max_priority,
max_start
) me ON
u.productkey = me.productkey AND
u.warehousekey = me.warehousekey AND
u.priority = me.max_priority AND
u.startdate = me.max_start AND
u.enddate = me.min_end)
返回:
PRODUCTKEY WAREHOUSEKEY STARTDATE ENDDATE PRIORITY UNITPRICE
36975 0 20121018 20291231 0 371
36975 0 20120630 20121011 0 395
36975 0 20121126 20121211 100 313
36975 0 20121212 20291231 100 313
36975 0 20121126 20121219 100 288
36975 6 20120630 20121011 0 395
36975 6 20121018 20291231 0 371
36975 6 20121126 20121211 120 313
36975 6 20121126 20121219 120 288
36975 6 20121212 20291231 120 313