我工作的公司转售数据,所以有可能同一个“单位”出售两次。我试图做盈利能力的计算,但遇到了一个头痛,因为如何设置表。
基本上我们有两个表,我们称之为数据表和销售表。
数据:
dataid cost
1 $1.00
2 $2.00
减价
saleid dataid price
1 1 $5.00
2 2 $3.00
3 2 $4.00
我需要做的是加入表格的方式,使成本只计算在其首次销售。这样地:
利润:
saleid dataid price cost profit
1 1 $5.00 $1.00 $4.00
2 2 $3.00 $2.00 $1.00
3 2 $4.00 $0.00 $4.00
我工作了将近十亿行,所以性能也是一个问题。我意识到表结构非常愚蠢,但重构数据库不是一个选择。有什么建议吗?
最佳答案
或者你也可以尝试一下,使用gordon linoff在前面的答案中建议的row_number()来确定首次销售。
数据:
IF ( OBJECT_ID('tempdb..#TmpData') IS NOT NULL )
BEGIN
DROP TABLE #TmpData
END
CREATE TABLE #TmpData ( dataid INT, cost MONEY, )
CREATE CLUSTERED INDEX IX_TmpData_dataid ON #TmpData (dataid)
INSERT INTO #TmpData
( dataid, cost )
VALUES ( 1, 1 ),
( 2, 2 )
IF ( OBJECT_ID('tempdb..#TmpSale') IS NOT NULL )
BEGIN
DROP TABLE #TmpSale
END
CREATE TABLE #TmpSale
(
saleid INT ,
dataid INT ,
price MONEY
)
CREATE CLUSTERED INDEX IX_TmpSale ON #TmpSale (saleid)
CREATE NONCLUSTERED INDEX IX_TmpSale_dataid ON #TmpSale (dataid)
INSERT INTO #TmpSale
( saleid, dataid, price )
VALUES ( 1, 1, 5 ),
( 2, 2, 3 ),
( 3, 2, 4 )
使用CTE和行数:
;WITH PROFIT
AS ( SELECT d.dataid d_dataid ,
d.cost ,
s.saleid ,
s.dataid s_dataid ,
price ,
ROW_NUMBER() OVER ( PARTITION BY d.dataid ORDER BY s.saleid ) ctr
FROM #TmpData D
JOIN #TmpSale S ON S.dataid = D.dataid
)
SELECT saleid ,
d_dataid dataid ,
price ,
IIF(ctr = 1, cost, 0) cost ,
IIF(ctr = 1, ( price - cost ), price) profit
FROM PROFIT
OPTION (MAXRECURSION 32767)
结果:
saleid dataid price cost profit
----------- ----------- ------- ------- --------
1 1 5.00 1.00 4.00
2 2 3.00 2.00 1.00
3 2 4.00 0.00 4.00
关于sql - SQL Server-处理奇怪的表关系,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44557624/