`
eyesmore
  • 浏览: 378650 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

用Linux命令行实现SQL的groupby

阅读更多

用Linux命令行实现SQL的groupby

  • 需求

给定一个sql脚本文件,里面全是insert操作,样例如下:
insert into `passport_daily` (uid,loginname,ip,operatetime,result) values ('9454268',' 876334249@qq.com','222.168.129.186','1281801604225','register');
insert into `passport_daily` (uid,loginname,ip,operatetime,result) values ('9454269',' 375682141@qq.com','60.181.1.247','1281801607618','register');
insert into `passport_daily` (uid,loginname,ip,operatetime,result) values ('9036732','670981425@qq.com','118.112.144.140','1281801609235','login');
insert into `passport_daily` (uid,loginname,ip,operatetime,result) values ('9454270',' 35845122@qq.com','111.112.18.214','1281801612152','register');
insert into `passport_daily` (uid,loginname,ip,operatetime,result) values ('8363103','jianglong418@126.com','113.106.101.3','1281801615463','login');

关系表(uid,loginname,ip,operatetime,result)的语义是:某某用户(账号ID是:uid,登录名是:loginname)在operatetime时间按从源IP执行了一个result操作。

现在需要统计:来自不同的IP分别有多少?  限用Linux命令统计。

  • 实现结果

gawk -F "','"  '{ print $3 }' sql.txt | sort -T ./ | uniq -c | sort -k 1 -nrs -T ./ > sql-stat.txt

23  60.181.1.247
9  111.112.18.214
5  113.106.101.3
1  118.112.144.140
1    222.168.129.186

  • 命令解释
  • gawk

gawk -F "','"  '{ print $3 }' sql.txt   表示从sql.txt文件中读取第三列。其中列分割符是’,’ (包含三个字符),由于列分割符号超过三个字符可使用双引号或单引号包围。由于此处分割符’,’中已经有单引号,所以使用双引号包围。
命令选项:
-F fs                   --field-separator=fs   用来指定列分割符号

insert into `passport_daily` (uid,loginname,ip,operatetime,result) values ('9454268',' 876334249@qq.com','222.168.129.186','1281801604225','register');

当然通过grep+正则表达式也可以提取IP地址:
grep -P '([0-9]{1,3}\.){3}[0-9]{1,3}' sql.txt –o

  • uniq

-c, --count           prefix lines by the number of occurrences (统计功能)
-d, --repeated        only print duplicate lines  (只找出重复行)
-u, --unique          only print unique lines   (只找出单行)

-f, --skip-fields=N   avoid comparing the first N fields  (对于有文件头的文件可以忽略前N行)

但是uniq命令有个前提:重复,单行的判断依据是只跟前后几行对比,并不是全文对比。所以执行uniq前一般先要sort。
Discard all but one of successive identical lines from INPUT (or
standard input), writing to OUTPUT (or standard output).

实例1:假设t1.txt文件如下
1
2
1
# uniq -u t1.txt        (虽然有两个1,但是不是连续的,依然会作为单行)
1
2
1
实例2:假设t2.txt文件如下
1
1
2
# uniq -u t2.txt    (连续的两个1,被认为是冗余行,所以取单行时被删除了)
2

  • Sort

-n,-r选项
-n, --numeric-sort  compare according to string numerical value  作为数字,而不是作为字母
-r, --reverse  reverse the result of comparisons  倒序
-s, --stable              stabilize sort by disabling last-resort comparison 如果希望稳定排序,则使用-s。所谓“稳定排序”举个例子,两个二元组原始顺序:(1,zhangsan), (1,lisi); 如果稳定排序,那么排序的结果始终会是(1,zhangsan)在(1,lisi)前面;非稳定的,那么(1,lisi)可能会排(1,zhangsan)的前面。
-k , -t 选项
-k, --key=POS1[,POS2]     start a key at POS1, end it at POS2 (origin 1)
-t, --field-separator=SEP  use SEP instead of non-blank to blank transition

这两个选项可以让我们指定排序关键字。
假如有三行(uid,name,ip,state):
8345891, zhangsan, 201.22.135.64, 0
3845891, wangwu, 69.22.136.64, 1
3845891, wangwu2, 198.22.16.164, 1

那么,如果按uid升序排序:
# sort -k 1 -t ',' -n s.txt   (-t 是字段分割符,-k用来指定排序关键字(可以是多个))
3845891, wangwu2, 198.22.16.164, 1  (非稳定排序,尽管wangwu和wangwu2的uid都是:3845891,但是wangwu2排wangwu前面去了。)
3845891, wangwu, 69.22.136.64, 1
8345891, zhangsan, 201.22.135.64, 0

# sort -k 1 -t ',' -n s.txt –s (稳定排序,wangwu依然在wangwu2的前面)
3845891, wangwu, 69.22.136.64, 1
3845891, wangwu2, 198.22.16.164, 1
8345891, zhangsan, 201.22.135.64, 0

# sort -k 2 -t ','  s.txt -s  (以第二个减排序)
3845891, wangwu2, 198.22.16.164, 1
3845891, wangwu, 69.22.136.64, 1
8345891, zhangsan, 201.22.135.64, 0

-T 选项
-T, --temporary-directory=DIR  use DIR for temporaries, not $TMPDIR or /tmp;
                              multiple options specify multiple directories

-T是用来指定临时目录的。因为sort排序过程中间可能需要用到一些临时文件作为交换空间,默认情况下这些临时文件会保存在$TMPDIR或/tmp中,但是我们也可以通过-T参数来指定。这个参数一般用在如果待排序文件特别大,默认临时目录可能没有足够空间。有个帖子说明了这一点:
http://stackoverflow.com/questions/3451388/perl-sort-temporary-directory

I ran into space issues on my machine and therefore the sort command in unix failed because of lack of space in /tmp. In order to circumvent this, I decided to run sort with the -T option allowing it to use some other directory for creating temporary files. here is the perl script I have
   my $TMPDIR              = "/home/xyz/workspace/";
    my $sortCommand         = "awk 'NR == 1; NR > 1 { print \$0 | \"sort -T \$TMPDIR -k1,1\" }' test > test.sort";
    system_call($sortCommand, "Sort");
    sub system_call {
      .......
}
this works perfectly on my desktop.

  • 总结

gawk -F "','"  '{ print $3 }' sql.txt | sort -T ./ | uniq -c | sort -k 1 -nrs -T ./ > sql-stat.txt

(1)    gawk -F "','"  '{ print $3 }' sql.txt 用来从sql.txt文件中取出IP列;
(2)    sort -T ./ | uniq –c  用来统计各个IP的数量。由于uniq –c统计的前提是相同的元素得相邻,所以之前得对输入进行排序。另外考虑到待排序输入流很大,默认临时空间可能不够,因此指定临时空间为当前目录。
(3)    sort -k 1 -nrs -T ./  按第一列,以数字,倒序排列,而且是稳定排序。(原本只有一个IP列,但是uniq –c后,在前面插入了统计量,因此变成两列了。)
(4)    > sql-stat.txt  将结果重定向输出到sql-stat.txt文件。

分享到:
评论

相关推荐

    Linux+Sql命令

    Linux命令行是Linux系统中最强大的工具之一,它允许用户通过文本界面执行各种任务,如文件管理、系统控制、网络操作等。一些常用的Linux命令包括: 1. **ls**:列出目录内容。 2. **cd**:改变当前工作目录。 3. **...

    js sql 数据库 linux

    对于更复杂的查询,可以使用`JOIN`、`WHERE`、`GROUP BY`等子句来优化数据检索。 在Linux环境中,管理数据库服务通常涉及启动、停止、重启服务,以及监控性能和日志。例如,使用`systemctl`或`service`命令管理...

    SQLServer的简介和使用

    - **数据分组与汇总**:利用GROUP BY和聚合函数对数据进行分组并计算总计。 - **多表连接**:掌握不同类型的连接(内连接、外连接等)。 - **子查询**:使用嵌套查询解决复杂问题。 - **更改数据**:学习如何修改已...

    MySQL5.7 group by新特性报错1055的解决办法

    如果你的SQL语句中包含未在`GROUP BY`子句中列出但未使用聚合函数的列,可以使用`ANY_VALUE()`函数来指定任意一个分组内的值。例如,如果你的查询原本是: ```sql SELECT column1, column2 FROM table GROUP BY ...

    sql一些基础、linux、数据结构简易版

    - GROUP BY:用于将数据分组,常与聚合函数(如COUNT、SUM、AVG、MAX、MIN)一起使用,进行统计分析。 - HAVING:在分组后对结果进行过滤。 Linux是一种广泛使用的开源操作系统,对于IT专业人士来说,熟悉Linux...

    SQL相关操作和使用文档 适合入门

    - 使用命令行或图形化工具连接MySQL服务器,执行SQL语句。 8. 学习资源与实践: - 参考官方文档和在线教程,如MySQL手册和W3School。 - 实际动手操作,通过创建数据库、表,练习SQL查询。 - 使用MySQL练习平台...

    SQLite命令行讲解

    此外,还可以进行连接(JOIN)、分组(GROUP BY)、排序(ORDER BY)等复杂查询。 SQLite还支持事务处理,确保数据一致性。例如: ```sql BEGIN; -- 执行一系列操作 COMMIT; ``` 如果在事务中遇到错误,可以使用`...

    cpp-fselect实现采用类似于SQL的语法来查找文件

    在SQL中,我们可以使用WHERE子句定义条件,JOIN操作合并不同表的数据,GROUP BY对数据进行分组,以及ORDER BY对结果排序。在`fselect`中,这些概念可能被转化为针对文件属性的操作,如文件名、大小、修改时间等。 ...

    sql.zip_DEMO_edb sqlite

    6. **SELECT**:查询数据,是最常用的SQL语句,可以结合WHERE、GROUP BY、HAVING、ORDER BY、LIMIT等子句进行复杂查询。 7. **UPDATE**:更新表中的数据。 8. **DELETE FROM**:删除表中的数据。 9. **JOIN**:将多...

    程序员的SQL金典 PDF扫描版

    - **分组与聚合函数**:GROUP BY进行分组,配合COUNT、SUM、AVG等聚合函数使用。 #### 8. 触发器与存储过程 - **触发器**:当特定事件发生时自动执行的一段SQL代码。 - **存储过程**:预先编写并编译好的一系列SQL...

    SQL数据库安装简明教程SQL

    除了基本操作,SQL还支持更复杂的查询,如JOIN用于合并多个表的数据,GROUP BY和HAVING用于分组和过滤,以及子查询和联接操作。此外,索引的创建和优化也是提高数据库性能的关键,你可以为经常查询的列创建索引以...

    DB2中查找消耗CPU的SQL

    - 运行一条示例SQL语句来触发监控,例如:`db2 "SELECT COUNT(a.empno), b.deptno, b.deptname FROM employee a, department b WHERE a.workdept = b.deptno GROUP BY b.deptno, b.deptname"`。 - 此SQL语句用于...

    mysql中文手册-linux

    5. **SQL查询语句**:学习SELECT、INSERT、UPDATE、DELETE基本操作,以及更复杂的JOIN、GROUP BY、HAVING、ORDER BY和子查询。 6. **索引**:理解索引的概念,如何创建和使用索引提高查询效率。 7. **存储过程和...

    Linux下的MySQL数据库编程_代码

    学会使用WHERE子句进行条件筛选,GROUP BY进行分组,ORDER BY进行排序,HAVING进行条件过滤。 5. **SQL查询优化**:了解如何编写高效的SQL查询,如避免全表扫描,使用索引,合理设计数据库模式以减少JOIN操作,以及...

    PyPI 官网下载 | python-sql-0.6.tar.gz

    可以使用Python的`tarfile`模块或者在命令行中使用`tar -xvf python-sql-0.6.tar.gz`命令来解压。解压后,你将看到一个包含源码和其他资源的目录结构。接着,你可以阅读`README`文件或`setup.py`文件了解如何安装和...

    cmd操作命令和linux命令大全收集

    3. Nslookup-------IP地址侦测器 ,是一个 监测网络中 DNS 服务器是否能正确实现域名解析的命令行工具。它在 Windows NT/2000/XP 中均可使用,但在 Windows 98 中却没有集成这一个工具。 4. explorer-------打开...

    mysql,linux shell学习进阶.zip

    - 查询操作:熟练使用SELECT语句进行复杂查询,包括JOIN、WHERE子句、GROUP BY、HAVING等。 - 存储引擎:理解InnoDB和MyISAM两种主要存储引擎的差异和适用场景。 - 触发器和存储过程:学习编写触发器来响应特定...

    Linux下mysql学习笔记

    `,排序`ORDER BY col_name ASC/DESC`,分组`GROUP BY col_name`。 3. 更新数据:`UPDATE tbl_name SET col1=value1 WHERE condition;` 4. 删除数据:`DELETE FROM tbl_name WHERE condition;` 五、权限与用户管理 ...

    MySQL.rar_sql

    可以结合WHERE子句进行条件查询,GROUP BY进行分组,HAVING进行分组后的条件过滤,ORDER BY进行排序,LIMIT限制返回结果的数量。 5. 其他高级概念:JOIN用于连接两个或更多表,子查询嵌套在其他查询中,视图(VIEW...

Global site tag (gtag.js) - Google Analytics