我有一张看起来像的表,
CREATE TABLE #tmpPercentage
(
ID INT,
V1 VARCHAR(10),
V2 FLOAT
);
INSERT INTO #tmpPercentage (ID, V1, V2)
VALUES (1, 'X', 10),
(1, 'Y', 7),
(1, 'Z', ?),
(2, 'X', 15),
(2, 'Y', 19),
(2, 'Z', ?);
Z的V2将是(V2 for X * V2 for Y)/100
,即x和y之间的百分比。
我该如何计算?我是SQL的新手。提前致谢
答案 0 :(得分:0)
将X
和Y
条记录转移到每个ID
的列中,然后进行计算
这是一种方式
select ID,
Z = (max(case when V1 = 'X' then V2 end) * max(case when V1 = 'Y' then V2 end))/100.0
From #tmpPercentage
Group by ID
以上Select
可以转换为Update
查询
;WITH cte
AS (SELECT ID,
Z = ( Max(CASE WHEN V1 = 'X' THEN V2 END) * Max(CASE WHEN V1 = 'Y' THEN V2 END) ) / 100.0
FROM #tmpPercentage
GROUP BY ID)
UPDATE t
SET V2 = c.z
FROM #tmpPercentage t
JOIN cte c
ON t.ID = c.ID
WHERE v1 = 'Z'
考虑到每个X
只有一个Y
和ID
值。如果X
的值超过Y
和ID
,则将Max
汇总为Sum
或Avg
或Min
根据您的要求。
答案 1 :(得分:0)
CREATE TABLE #tmpPercentage
( ID INT,
V1 VARCHAR(10),
V2 FLOAT);
INSERT INTO #tmpPercentage
(ID, V1, V2)
VALUES (1, 'X', 10),
(1, 'Y', 7),
(2, 'X', 15),
(2, 'Y', 19),
然后,分别为Z
执行插入:
insert into #tmpPercentage
select id, 'Z',
(max(case when V1 = 'X' then V2 end) * max(case when V1 = 'Y' then V2 end))/100.0
from #tmpPercentage
group by id, 'Z';
答案 2 :(得分:0)
; WITH tmpPercentage (ID,V1, V2) AS (
SELECT 1, 'X', 10 UNION ALL
SELECT 1, 'Y', 7 UNION ALL
SELECT 1, 'Z', NULL UNION ALL
SELECT 2, 'X', 15 UNION ALL
SELECT 2, 'Y', 19 UNION ALL
SELECT 2, 'Z', NULL
)
SELECT ID, MAX(CASE WHEN v1='X' THEN V2 ELSE 0 END) * MAX(CASE WHEN v1='Y' THEN V2 ELSE 0 END)/100.0 AS Z FROM tmpPercentage
GROUP BY ID
ID Z ----------- --------------------------------------- 1 0.700000 2 2.850000
SELECT ID,V1,CASE WHEN V1='Z' THEN
MAX(CASE WHEN v1='X' THEN V2 ELSE 0 END) OVER(PARTITION BY ID)
* MAX(CASE WHEN v1='Y' THEN V2 ELSE 0 END)OVER(PARTITION BY ID)/100.0 ELSE V2 END AS V2
FROM tmpPercentage
ID V1 V2 ----------- ---- --------------------------------------- 1 Y 7.000000 1 Z 0.700000 1 X 10.000000 2 Y 19.000000 2 Z 2.850000 2 X 15.000000
答案 3 :(得分:0)
您可以使用下面的CTE
来处理此问题,而无需更改记录的顺序以及单个INSERT
语句和UPDATE
语句。
注意:只需将以下语句复制并粘贴到您的本地计算机上,然后尝试一下它就像魅力一样: - )
CREATE TABLE #tmpPercentage
( ID INT,
V1 VARCHAR(10),
V2 FLOAT);
;WITH tmpPercentage0 AS (
SELECT 1 AS ID, 'X' AS V1, 10 AS V2
UNION
SELECT 1 AS ID, 'Y' AS V1, 7 AS V2
UNION
SELECT 1 AS ID, 'Z' AS V1, NULL AS V2
UNION
SELECT 2 AS ID, 'X' AS V1, 15 AS V2
UNION
SELECT 2 AS ID, 'Y' AS V1, 19 AS V2
UNION
SELECT 2 AS ID, 'Z' AS V1, NULL AS V2
),
tmpPercentage1 AS (
SELECT
*, ROW_NUMBER() OVER (ORDER BY ID) AS RowNumber
FROM
tmpPercentage0
)
INSERT INTO #tmpPercentage
(ID,
V1,
V2)
SELECT
ID, V1, (
CASE
WHEN V1 = 'Z' THEN (
(
(SELECT CONVERT(FLOAT, V2) FROM tmpPercentage1 WHERE RowNumber = tp1.RowNumber - 2)
*
(SELECT CONVERT(FLOAT, V2) FROM tmpPercentage1 WHERE RowNumber = tp1.RowNumber - 1)
) / 100
)
ELSE V2
END) AS V2
FROM
tmpPercentage1 tp1
答案 4 :(得分:0)
如果您使用的是较新版本的sql-server(例如2012),则可以使用 LAG 功能,该功能可以返回上一行 -
SELECT ID, V1
, CASE
WHEN V1 = 'Z'
THEN ((LAG (V2, 1) OVER (PARTITION BY ID ORDER BY V1)) * (LAG (V2, 2) OVER (PARTITION BY ID ORDER BY V1))) / 100
ELSE V2
END AS V2
FROM #tmpPercentage;
下面
((LAG (V2, 1) and LAG (V2, 2)
分别返回当前行之前的V2和前两行的V2。
OVER (PARTITION BY ID ORDER BY V1))
这确保了我们首先使用PARTITION BY在每个ID上应用LAG 然后在ORDER BY子句上使用V1对x,y,z中的行进行排序。因此,对于z存在所有x,y是很重要的。但是,即使对于随机排序的数据,此查询也会返回正确的结果 -
INSERT INTO #tmpPercentage
(ID, V1, V2)
VALUES (1, 'X', 10),
(2, 'X', 15),
(1, 'Z', NULL),
(2, 'Y', 19),
(2, 'Z', NULL),
(1, 'Y', 7);
<强>输出强>
| ID | V1 | V2 |
|----|----|------|
| 1 | X | 10 |
| 1 | Y | 7 |
| 1 | Z | 0.7 |
| 2 | X | 15 |
| 2 | Y | 19 |
| 2 | Z | 2.85 |
注意:此查询应该比使用子查询的任何其他版本更快。