python写mysql函数_MySQL 以及 Python 实现排名窗体函数

大部分数据库都提供了窗体函数。比方RANK,ROW_NUMBER等等。 MySQL 这方面没有直接提供。可是能够变相的实现。我曾经写了row_number 的实现,今天有时间把 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()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值