嗨我怎样才能得到每个记录在总数中的百分比? 让我们来想象我有以下SQL占总数的百分比
ID code Points
1 101 2
2 201 3
3 233 4
4 123 1
为ID 1
的比例为20%
是2
30%
等一个 我怎么得到它的一个表?
嗨我怎样才能得到每个记录在总数中的百分比? 让我们来想象我有以下SQL占总数的百分比
ID code Points
1 101 2
2 201 3
3 233 4
4 123 1
为ID 1
的比例为20%
是2
30%
等一个 我怎么得到它的一个表?
尝试这样
select id,code,points,(points * 100)/(select sum(points) from tabel1) from table1
完美地工作谢谢 – Joaquim 2014-10-09 13:58:14
有几种方法可以得到那个结果。
你基本上需要整个表格(或任何子集)中的“总”点数,并在每一行上重复。获取百分比是一个简单的算术问题,您使用的表达式取决于数据类型,以及您希望如何格式化。
这里有一种方法(出几个可能的方式),以获得特定的结果:
SELECT t.id
, t.code
, t.points
-- , s.tot_points
, ROUND(t.points * 100.0/s.tot_points,1) AS percentage
FROM onetable t
CROSS
JOIN (SELECT SUM(r.points) AS tot_points
FROM onetable r
) s
ORDER BY t.id
查询s
首先运行的观点,给人的单行。连接操作将该行与来自t
的每一行进行匹配。这给了我们需要计算一个百分比的价值。
在不使用连接操作的情况下获得此结果的另一种方法是使用SELECT列表中的子查询返回总数。
请注意,可以扩展连接方法以获取每个“组”记录的百分比。
id type points %type
-- ---- ------ -----
1 sold 11 22%
2 sold 4 8%
3 sold 25 50%
4 bought 1 50%
5 bought 1 50%
6 sold 10 20%
为了得到这一结果,我们可以使用相同的查询,但对于s
AA视图查询,返回总GROUP BY r.type
,然后加入操作是不是一个交叉连接,而是基于类型匹配:
SELECT t.id
, t.type
, t.points
-- , s.tot_points_by_type
, ROUND(t.points * 100.0/s.tot_points_by_type,1) AS `%type`
FROM onetable t
JOIN (SELECT r.type
, SUM(r.points) AS tot_points
FROM onetable r
GROUP BY r.type
) s
ON s.type = t.type
ORDER BY t.id
要做到这一点相同的结果与子查询,这将是一个相关子查询,而查询是有可能得到t
的每一行执行。
这就是为什么使用连接操作而不是SELECT列表中的子查询更自然,即使子查询的工作原理相同。 (我们用于更复杂查询的模式,比如为表分配别名,限定所有列引用以及格式化SQL ......这些模式只是回到简单的查询中,这些模式的原理有点简单。查询)
有些无关的问题:数据库能够检测到子查询的结果是不变的,因此只评估一次? – 2014-10-01 12:27:12
@Martin Thurau:是的,一个好的优化器应该认识到子查询可以运行一次,然后使用该常量。 (有效地将选择列表中的子查询转换为查询中指定的相同操作,但如果是相关的子查询,优化器不会这样做;假设您获得了不同类型的总点数(称为“买入”和“卖出“),并且你想要一个基于类型的百分比,很容易通过连接得到一个有效的计划;如果你在选择列表中使它成为一个相关的子查询,那么这个子查询将会被执行到每一行。 – spencer7593 2014-10-01 12:37:18
为了增加响应良好的名单,这应该是快速的性能,明智的,而且比较容易理解:
DECLARE @T TABLE (ID INT, code VARCHAR(256), Points INT)
INSERT INTO @T VALUES (1,'101',2), (2,'201',3),(3,'233',4), (4,'123',1)
;WITH CTE AS
(SELECT * FROM @T)
SELECT C.*, CAST(ROUND((C.Points/B.TOTAL)*100, 2) AS DEC(32,2)) [%_of_TOTAL]
FROM CTE C
JOIN (SELECT CAST(SUM(Points) AS DEC(32,2)) TOTAL FROM CTE) B ON 1=1
刚刚与CTE里面你实际的表替换表变量。
我们应该注意到该语法不适用于其他数据库(例如Oracle,MySQL,Teradata等) – spencer7593 2014-10-01 12:48:34
是的,真的,Darn,我为我的搜索标记了sql-server,但这只是SQL。:(但是,这个脚本确实是为SQL Server 2008及更高版本创建的。 – Kahn 2014-10-01 12:50:29
您正在使用哪个DBMS? – DirkNM 2014-10-01 12:17:22