MySQL 以及 Python 实现排名窗体函数
大部分数据库都提供了窗体函数。比方RANK,ROW_NUMBER等等。 MySQL 这方面没有直接提供。可是能够变相的实现。我曾经写了row_number 的实现,今天有时间把 rank 的实现贴出来。
表数据
PostgreSQL 的rank 窗体函数演示样例:
MySQL 提供了group_concat 聚合函数能够变相的实现:
当然了,假设MySQL SQL不太熟悉。能够用程序来处理,比方我以下用python 实现了rank 函数,运行结果例如以下:(脚本源码最后)
附上脚本代码:
这里,我用MySQL 以及Python 分别实现了rank 窗体函数。
原始表信息:
t_girl=# \d group_concat;
Table "ytt.group_concat"
Column | Type | Modifiers
----------+-----------------------+-----------
rank | integer |
username | character varying(20) | 表数据
t_girl=# select * from group_concat; rank | username ------+---------- 100 | Lucy 127 | Lucy 146 | Lucy 137 | Lucy 104 | Lucy 121 | Lucy 136 | Lily 100 | Lily 100 | Lily 105 | Lily 136 | Lily 149 | ytt 116 | ytt 116 | ytt 149 | ytt 106 | ytt 117 | ytt (17 rows) Time: 0.638 ms
PostgreSQL 的rank 窗体函数演示样例:
t_girl=# select username,rank,rank() over(partition by username order by rank desc) as rank_cnt from group_concat; username | rank | rank_cnt ----------+------+---------- Lily | 136 | 1 Lily | 136 | 1 Lily | 105 | 3 Lily | 100 | 4 Lily | 100 | 4 Lucy | 146 | 1 Lucy | 137 | 2 Lucy | 127 | 3 Lucy | 121 | 4 Lucy | 104 | 5 Lucy | 100 | 6 ytt | 149 | 1 ytt | 149 | 1 ytt | 117 | 3 ytt | 116 | 4 ytt | 116 | 4 ytt | 106 | 6 (17 rows) Time: 131.150 ms
MySQL 提供了group_concat 聚合函数能够变相的实现:
mysql> select a.username, a.rank, find_in_set(a.rank,b.rank_gp) as rank_cnt from group_concat as a , (select username,group_concat(rank order by rank desc separator ',') as rank_gp from group_concat group by username ) b where a.username = b.username order by a.username asc,a.rank desc; +----------+------+----------+ | username | rank | rank_cnt | +----------+------+----------+ | Lily | 136 | 1 | | Lily | 136 | 1 | | Lily | 105 | 3 | | Lily | 100 | 4 | | Lily | 100 | 4 | | Lucy | 146 | 1 | | Lucy | 137 | 2 | | Lucy | 127 | 3 | | Lucy | 121 | 4 | | Lucy | 104 | 5 | | Lucy | 100 | 6 | | ytt | 149 | 1 | | ytt | 149 | 1 | | ytt | 117 | 3 | | ytt | 116 | 4 | | ytt | 116 | 4 | | ytt | 106 | 6 | +----------+------+----------+ 17 rows in set (0.02 sec)
当然了,假设MySQL SQL不太熟悉。能够用程序来处理,比方我以下用python 实现了rank 函数,运行结果例如以下:(脚本源码最后)
>>> ================================ RESTART ================================ >>> username | rank | rank_cnt -------------------------------- ytt |149 |1 ytt |149 |1 ytt |117 |3 ytt |116 |4 ytt |116 |4 ytt |106 |6 Lucy |146 |1 Lucy |137 |2 Lucy |127 |3 Lucy |121 |4 Lucy |104 |5 Lucy |100 |6 Lily |136 |1 Lily |136 |2 Lily |105 |3 Lily |100 |4 Lily |100 |4 (17 Rows.) Time: 0.162 Seconds.
附上脚本代码:
from __future__ import print_function
from datetime import date, datetime, timedelta
import mysql.connector
import time
# Created by ytt 2014/5/14.
# Rank function implement.
def db_connect(is_true):
cnx = mysql.connector.connect(host='192.168.1.131',port='3306',user='python_user', password='python_user',database='t_girl',autocommit=is_true)
return cnx
def db_rs_rank(c1 ='username desc' ,c2 = ' rank desc'):
# c1: partition column.
# c2: sort column.
time_start = time.time()
cnx = db_connect(True)
rs = cnx.cursor()
query0 = "select username,rank from group_concat order by " + c1 + ", " + c2
rs.execute(query0,multi=False)
if rs.with_rows:
rows = rs.fetchall()
else:
return "No rows affected."
i = 0
j = 0
k = 1
result = []
field1_compare = rows[0][0]
field2_compare = rows[0][1]
while i < len(rows):
if field1_compare == rows[i][0]:
j += 1
if field2_compare != rows[i][1]:
field2_compare =rows[i][1]
k = j
result.append((rows[i][0],rows[i][1],k))
else:
j = 1
k = 1
field1_compare = rows[i][0]
result.append((rows[i][0],rows[i][1],k))
i += 1
i = 0
rows_header = list(rs.column_names)
rows_header.append('rank_cnt')
print (rows_header[0].center(10,' ') + '|' + rows_header[1].center(10,' ') + '|' + rows_header[2].center(10,' '))
print ('-'.center(32,'-'))
while i < len(result):
print (result[i][0].ljust(10,' ') + '|' + str(result[i][1]).ljust(10,' ') + '|' + str(result[i][2]).ljust(10,' '))
i += 1
rs.close()
cnx.close()
time_end = time.time()
print ('(' + str(len(rows))+ ' Rows.)')
print ("Time:" + str(round((time_end-time_start),3)).rjust(10,' ') + ' Seconds.')
if __name__=='__main__':
db_rs_rank()
浙公网安备 33010602011771号