我们说我有以下
Col1 Col2
1 A
1 A
1 A
1 B
1 B
1 B
1 B
2 A
2 A
2 B
3 A
3 A
3 A
3 A
3 A
3 A
我需要做的是编写一个查询,确定Col1和Col2的每个组合的记录数,并将该数除以1并将该值分配给新列(Col3),但是我还需要更新记录在某些情况下,当对新列进行求和时,它总是为Col1和Col2的每个组合添加一个。
所以,在第一步中我会以
结束Col1 Col2 NumberofRows
1 A 3
1 B 4
2 A 2
2 B 1
3 A 6
当除以1时产生
Col1 Col2 Col3
1 A 0.33
1 A 0.33
1 A 0.33
1 B 0.25
1 B 0.25
1 B 0.25
1 B 0.25
2 A 0.5
2 A 0.5
2 B 1
3 A 0.17
3 A 0.17
3 A 0.17
3 A 0.17
3 A 0.17
3 A 0.17
然而,当将Col3归为Col1 = 1且Col2 = A时,由于显而易见的原因,我们最终得到0.99而不是1。类似地,对Col3求和,其中Col1 = 3,Col2 = A,我们最终得到1.02。
我该怎么做?
答案 0 :(得分:0)
如果SQL Server可以表示为整数除以十的倍数,则它只能存储确切的数字。由于三分之一不能以这种方式表达,因此SQL Server无法存储三分之一而不会丢失精度。
更好的选择是存储行数。行计数是整数,SQL Server可以存储它们而不会损失精度。它们将完全相加总行数。如果您显示该行,则可以显示1/rc
。您显示的内容永远不会加起来,但这是以十进制形式显示数字的限制。
如果可以将数字显示为分数,您可以:
select '1/' + cast(rc as varchar(20))
答案 1 :(得分:0)
我尝试过使用CTE。 请检查我的方法:
;WITH c1
AS
( SELECT col1, col2, count(*) as Cnt
FROM test
GROUP BY col1, col2
),
c2
AS
( SELECT t.col1, t.col2, cast(cast(1 as decimal(5, 2))/grpCount.Cnt as decimal(5, 2))
AS Cnt, 1%grpCount.Cnt AS roundedCount
FROM test t
JOIN (SELECT * FROM c1) AS grpCount
ON grpCount.col1 = t.col1 AND grpCount.col2 = t.col2
)
SELECT * FROM c2;
SQL小提琴: - http://sqlfiddle.com/#!6/fe268/7
答案 2 :(得分:0)
您需要确保SQL将中间值用作浮点数,但在显示时将其转换为十进制2 d.p
MS SQL Server 2012架构设置:
CREATE TABLE tableA
(
Col1 int,
Col2 VARCHAR(1)
)
INSERT INTO tableA
VALUES
(1,'A'),
(1,'A'),
(1,'A'),
(1,'B'),
(1,'B'),
(1,'B'),
(1,'B'),
(2,'A'),
(2,'A'),
(2,'B'),
(3,'A'),
(3,'A'),
(3,'A'),
(3,'A'),
(3,'A'),
(3,'A')
查询1 :
;WITH cnt
AS
(
SELECT Col1, Col2, 1.0 / COUNT(*) cnt
FROM tableA
GROUP BY Col1, Col2
)
SELECT A.Col1, A.Col2, CAST(SUM(cnt) AS decimal(4,2))
FROM tableA A
INNER JOIN cnt
ON A.Col1 = cnt.Col1 AND A.Col2 = cnt.Col2
GROUP BY A.Col1, A.Col2
<强> Results 强>:
| COL1 | COL2 | COLUMN_2 |
|------|------|----------|
| 1 | A | 1 |
| 1 | B | 1 |
| 2 | A | 1 |
| 2 | B | 1 |
| 3 | A | 1 |