使用 Tcl 和 Mysql 进行统计

Statistics With Tcl And Mysql

我有一个 Mysql 门道数据库。

我们是一家小公司,不幸的是我不擅长编程,如果有人能帮助我,我会很高兴。我们在每扇门上都有带徽章的安全通道。我需要显示他进入了哪个名字和多少扇门的统计数据

这是 Mysql 数据库的样子:

ID  key         ctime       name    floor   floorid door
1   114554737   1609613062  work1   1       D1      112
2   114554737   1609662335  work1   1       D1      112
3   114554737   1609662388  work1   1       D1      115
4   114554737   1609665480  work1   2       D1      201
5   114554738   1609701179  work2   2       D1      202
6   114554738   1609701188  work2   1       D1      101
7   114554738   1609701195  work2   2       D1      225
8   114554738   1609701253  work2   3       D1      318
9   114554738   1609707953  work2   4       D1      412
10  114554738   1609876824  work2   5       D1      500
11  114554739   1609956064  work3   1       D1      100
12  114554739   1609956067  work3   1       D1      101
13  114554739   1610084925  work3   1       D1      100
14  114554739   1610084928  work3   1       D1      100
15  114554740   1610141106  work4   2       D1      201
16  114554740   1610141109  work4   2       D1      202
17  114554740   1610177322  work4   2       D1      202
18  114554740   1610178412  work4   2       D1      202
19  114554740   1610207104  work4   2       D1      202
20  114554741   1610216851  work5   2       D1      202
21  114554741   1610268582  work5   2       D1      202
22  114554741   1610268908  work5   2       D1      202
23  114554741   1610271923  work5   2       D1      206
24  114554741   1610275117  work5   2       D1      206
25  114554741   1610293137  work5   3       D1      301

我目前正在使用这个脚本

显示哪个名字最常进入哪扇门

package require mysqltcl
load /usr/lib/tcltk/x86_64-linux-gnu/mysqltcl-3.052/libmysqltcl3.052.so

set db_handle [mysqlconnect -host localhost -port 3306 -user xxx -pass xx -db doors]


bind pub -|- !ustats stats:ustats


proc stats:ustats { nick uhost hand chan text } {

    global db_handle

    set maxresults 50

    set sql "SELECT count(name) as namecount, key, ctime, name, floor, floorid, door from stats GROUP by name ORDER BY nickcount DESC"

    set result [mysqlsel $db_handle $sql -list];

    if {$result > 0} {
    set counter 1

    putnow "PRIVMSG #test :[=12=]315\[[=12=]314![=12=]315\]-\[[=12=]314Top Query Stats[=12=]315\]"

    for {set i 0} {$i < $maxresults} {incr i} {

    set record [lindex $result $i]
    set count [lindex $record 0] 
    set key [lindex $record 1]
    set ctime [lindex $record 2]
    set name [lindex $record 3]
    set floor [lindex $record 4]
    set floorid [lindex $record 5]
    set door [lindex $record 6]


    if {$count != ""} {

    putquick "PRIVMSG #chan :$counter $count $name $door $floor $floorid"
    incr counter
    }
    }
    } 
    mysqlendquery $db_handle
}

我需要一个输出,它不仅可以显示哪个名字打开的门最多,还可以显示哪些门和打开的门数以及从左边最大到右边最小的门数

示例:

  1. work2 总共打开了 6 次,1x 门 202,1x 门 101,1x 门 225,1x 门 318,1x 门 412,1x 门 500
  2. work5 总共打开了 6 次,3 次门 202,2 次门 206,1 次门 301
  3. work4 总共打开了 5 次,4 次门 202,1 次门 201
  4. work1 总共打开了 4 次,2 次门 112,1 次门 115,1 次门 201
  5. work3 总共打开了 4 次,3 次门 100,1 次门 101

你会非常帮助我,非常感谢你

此致

您在这里需要的是一个稍微复杂的 SQL 查询。它将由子查询组成。

第一个是这个(fiddle)。它会为您提供每个名称的开门物品总数。

 SELECT COUNT(*) total, name FROM stats GROUP BY name

下一个是这个(fiddle)。它会为您提供每扇门的打开次数和名称。

SELECT COUNT(*) bydoor, name, door FROM stats GROUP BY name, door

第三个(fiddle)合并了第二个,每个名字一行,表示开门。

SELECT name, 
       GROUP_CONCAT(CONCAT(bydoor,'X',' door ', door) ORDER BY bydoor DESC) details
  FROM (   SELECT COUNT(*) bydoor,
                  name,
                  door
             FROM stats
            GROUP BY name, door
        ) s
  GROUP BY name

最后,您需要一个 JOIN 将这些子查询连接在一起,这种形式。

   SELECT t.name, t.total, d.details
     FROM ( .... the first subquery ....) t
     JOIN ( .... the second subquery .... ) d ON t.name = d.name
    ORDER BY t.total DESC, t.name

所有拼写看起来像这样 (fiddle)。您将它放入您的 sql 变量中,您就可以开始了。它只是一个多行字符串。

set sql {SELECT t.name, t.total, d.details
  FROM (SELECT COUNT(*) total, name FROM stats GROUP BY name) t
  JOIN (  SELECT name, 
                 GROUP_CONCAT(CONCAT(bydoor,'X',' door ', door) ORDER BY bydoor DESC) details
            FROM (   SELECT COUNT(*) bydoor,
                            name,
                            door
                       FROM stats
                      GROUP BY name, door
                 ) s
           GROUP BY name
        ) d ON t.name = d.name
  ORDER BY t.total DESC, t.name}

所以有一个由一堆嵌套查询组成的查询。

这里有一些技巧供您学习,以便您在 SQL 数据分析方面做得更好。

  1. 使用GROUP BY
  2. 查询嵌套,也称为子查询。您可以将子查询视为虚拟表。
  3. (高级)GROUP_CONCAT.