我希望为我的数据做一种特殊的缩放。
是否可以在列中查询具有以下内容的数据库:
10
5
5
3
1
1
0
1
5
2
2
通过查询生成以下表示:
1.0
0.8
0.8
0.6
0.2
0.2
0.0
1.0
0.8
0.4
0.4
所以最大值变为1.0,0保持为0.然后我们得到一组不包括0的唯一值,即10,5,3,2,1。该集的长度为5.逆是0.2 。然后,我们的列中的下一个最大值5变为1 - 0.2 = 0.8。然后,下一个最大值3变为0.8-0.2 = 0.6,依此类推。
10->1.0, 5->0.8, 3->0.6, 2->0.4, 1->0.2, 0->0
或者您是否建议执行查询的编程语言应该执行此缩放。
我是唯一一个将要查询数据库的人,我还没有选择我的数据库,但将使用的是开源或SQL服务器。这种类型的缩放对我的应用程序非常重要,我将在不同的表上使用它。我将在Python3中编程。
修改 SQL Server也是一个选项,以及开源dbs
答案 0 :(得分:1)
我在理解你的算法时遇到了一些麻烦,但我建议用编程语言来执行这个逻辑。这可能更有效,更容易维护。
答案 1 :(得分:1)
我会推荐PHP:
$myColumnArray = /* load mysql values here */;
// order numbers smallest to largest
$uniqueElements = sort(array_unique($myColumnArray));
// calculate increment
$incriment = count($uniqueElements);
// go thru elements in orig array and replace with weighted value
foreach($myColumnArray as &$val){
// get position of element (i.e. "4th largest")
$position = array_search ($val, $uniqueElements);
// set it equal to weighted value
$val = $position * $increment;
}
答案 2 :(得分:0)
在宣布它可行之前,请给它一个很好的测试:
SELECT
Value,
rnk / cnt AS WhatYouCallIt
FROM (
SELECT
@rank := @rank + (t.Value <> @prev) AS rnk,
@prev := t.Value AS Value,
m.cnt
FROM atable t,
(SELECT COUNT(DISTINCT Value) AS cnt FROM atable WHERE Value > 0) m
(SELECT @prev := 0, @rank = 0) x
WHERE t.Value >= 0
) s
答案 3 :(得分:0)
SQL Server,Oracle等可以访问RANK()等分析函数。这些功能使这些问题非常易于管理。我不知道可以做到这一点的开源RDBMS。 (如果您建议您使用的特定RDBMS,并且它可以访问RANK(),我可以告诉您我是如何接近它的。)
如果没有此类分析功能,建议您最好在客户端代码中执行此操作。
首先,您需要知道有多少不同的值,以及它们是什么。
SELECT x FROM yourTable GROUP BY x ORDER BY x
一旦你有了这些值的数组,它就是一个简单的查找。对于结果集中的每个元素,请检查该值在查找表中占据的位置。然后你就得到了结果。
答案 4 :(得分:0)
尝试使用纯SQL - 没有分析函数:
SELECT
t.col AS oldvalue
, tr.rank / tc.cnt AS newvalue
FROM
tableX AS t
JOIN
( SELECT
t1.col
, COUNT(*) - 1 AS rank
FROM
( SELECT DISTINCT col
FROM tableX
) AS t1
JOIN
( SELECT DISTINCT col
FROM tableX
) AS t2
ON t2.col <= t1.col
GROUP BY t1.col
) AS tr
ON tr.col = t.col
CROSS JOIN
( SELECT COUNT(DISTINCT col) - 1 AS cnt
FROM tableX
) AS tc
答案 5 :(得分:0)
我认为这应该可行,因为我实际上在本专栏中没有任何0。我该如何优化这个sql server代码?
SELECT
count,
dense_rank() over(order by count) / CONVERT ( float, (SELECT COUNT(DISTINCT count) FROM db))
FROM db
谢谢!
答案 6 :(得分:0)
纯SQL解决方案。我建议使用MySQL,因为会话变量使这种类型的查询更容易。
SELECT
t.id AS 'original_value',
IF(st.rank IS NULL, 0.0, ((1.0 / st3.group_size) * (st3.group_size - st.rank + 1))) AS 'adjusted_values'
FROM
test t
LEFT JOIN (
SELECT
st1.id AS 'value',
@rank := @rank + 1 AS 'rank'
FROM
(SELECT @rank := 0) vars,
(SELECT DISTINCT id FROM test WHERE id <> 0 ORDER BY id DESC) st1) st ON t.id = st.value
INNER JOIN (
SELECT
1 AS 'group_by',
COUNT(*) AS 'group_size'
FROM
(SELECT DISTINCT id FROM test WHERE id <> 0 ORDER BY id DESC) st2
GROUP BY group_by) st3;
根据您的输入,它会产生:
original_value adjusted_values
-------------- ---------------
0 0
1 0.2
2 0.4
3 0.6
5 0.8
10 1
5 0.8
1 0.2
1 0.2
5 0.8
2 0.4