12
返回列表 发新帖
楼主: 喃喃

关于分组

[复制链接]
论坛徽章:
40
生肖徽章2007版:马
日期:2008-04-07 19:43:48管理团队成员
日期:2011-05-07 01:45:082012新春纪念徽章
日期:2012-02-13 15:08:092012新春纪念徽章
日期:2012-02-13 15:08:092012新春纪念徽章
日期:2012-02-13 15:08:092012新春纪念徽章
日期:2012-02-13 15:08:092012新春纪念徽章
日期:2012-02-13 15:08:09马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14
11#
发表于 2008-1-16 13:30 | 只看该作者
原帖由 喃喃 于 2008-1-16 09:15 发表
呵呵,可以这样实现

SELECT a.employee_id,
       a.department_id,
       a.salary
  FROM employees a
WHERE (SELECT COUNT(*)
          FROM employees b
         WHERE b.department_id = a.department_id
           AND b.salary > a.salary) < 3
ORDER BY a.department_id,
          a.salary DESC


这个很猛。

使用道具 举报

回复
论坛徽章:
40
生肖徽章2007版:马
日期:2008-04-07 19:43:48管理团队成员
日期:2011-05-07 01:45:082012新春纪念徽章
日期:2012-02-13 15:08:092012新春纪念徽章
日期:2012-02-13 15:08:092012新春纪念徽章
日期:2012-02-13 15:08:092012新春纪念徽章
日期:2012-02-13 15:08:092012新春纪念徽章
日期:2012-02-13 15:08:09马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14
12#
发表于 2008-1-16 13:41 | 只看该作者
原帖由 喃喃 于 2008-1-16 11:02 发表


不是我想出来的,是看了别人的帖子
也不是mysql特有的,是标准SQL


对了。你是在哪里看得。相关子查询的效率也是挺高的。刚次只是粗略的看了一下。

使用道具 举报

回复
论坛徽章:
40
生肖徽章2007版:马
日期:2008-04-07 19:43:48管理团队成员
日期:2011-05-07 01:45:082012新春纪念徽章
日期:2012-02-13 15:08:092012新春纪念徽章
日期:2012-02-13 15:08:092012新春纪念徽章
日期:2012-02-13 15:08:092012新春纪念徽章
日期:2012-02-13 15:08:092012新春纪念徽章
日期:2012-02-13 15:08:09马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14
13#
发表于 2008-1-16 13:43 | 只看该作者
看来还得继续努力学习。上次我记得我给人家写了一个SP。没想到这个SQL语句就能实现了。

使用道具 举报

回复
论坛徽章:
40
生肖徽章2007版:马
日期:2008-04-07 19:43:48管理团队成员
日期:2011-05-07 01:45:082012新春纪念徽章
日期:2012-02-13 15:08:092012新春纪念徽章
日期:2012-02-13 15:08:092012新春纪念徽章
日期:2012-02-13 15:08:092012新春纪念徽章
日期:2012-02-13 15:08:092012新春纪念徽章
日期:2012-02-13 15:08:09马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14
14#
发表于 2008-1-16 13:55 | 只看该作者
不过效率还是没有存储过程来的高

我的测试结果:
mysql> CREATE TABLE `t` (
    ->   `id` int(11) NOT NULL auto_increment,
    ->   `g_id` int(11) NOT NULL,
    ->   `t_str` varchar(255) NOT NULL,
    ->   PRIMARY KEY  (`id`)
    -> ) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.03 sec)

mysql>
mysql> /*Data for the table `t` */
mysql>
mysql> insert  into `t`(`id`,`g_id`,`t_str`) values (1,2,'wo'),(2,2,'ni'),(3,2,'ta'),(4,3,'wo '),(5,4,'ni'),(6,3,'ni'),(7,4,'ta'),(8,3,'wang'),(9,4,'li'),(10,3,'hai'),(11,4,'ri'),(12,2,'ren'),(13,5,'ta'),(14,6,'ri'),(15,6,'ren'),(16,6,'fuck'),(17,6,'shit'),(18,5,'ls'),(19,5,'chmod'),(20,5,'chgrp'),(21,5,'chown'),(22,3,'rm'),(23,3,'desc'),(24,4,'pwd'),(25,5,'cd');
Query OK, 25 rows affected (0.00 sec)
Records: 25  Duplicates: 0  Warnings: 0

mysql> create index f_g_id on t(g_id);
Query OK, 25 rows affected (0.04 sec)
Records: 25  Duplicates: 0  Warnings: 0

mysql> desc t;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| g_id  | int(11)      | NO   | MUL |         |                |
| t_str | varchar(255) | NO   |     |         |                |
+-------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

mysql> select * from t;
+----+------+-------+
| id | g_id | t_str |
+----+------+-------+
|  1 |    2 | wo    |
|  2 |    2 | ni    |
|  3 |    2 | ta    |
|  4 |    3 | wo    |
|  5 |    4 | ni    |
|  6 |    3 | ni    |
|  7 |    4 | ta    |
|  8 |    3 | wang  |
|  9 |    4 | li    |
| 10 |    3 | hai   |
| 11 |    4 | ri    |
| 12 |    2 | ren   |
| 13 |    5 | ta    |
| 14 |    6 | ri    |
| 15 |    6 | ren   |
| 16 |    6 | fuck  |
| 17 |    6 | shit  |
| 18 |    5 | ls    |
| 19 |    5 | chmod |
| 20 |    5 | chgrp |
| 21 |    5 | chown |
| 22 |    3 | rm    |
| 23 |    3 | desc  |
| 24 |    4 | pwd   |
| 25 |    5 | cd    |
+----+------+-------+
25 rows in set (0.00 sec)

mysql> SELECT a.* FROM t a WHERE
    -> (
    -> SELECT COUNT(*) FROM t b WHERE a.g_id = b.g_id AND b.id<a.id
    -> ) < 2 ORDER BY a.g_id DESC;
+----+------+-------+
| id | g_id | t_str |
+----+------+-------+
| 15 |    6 | ren   |
| 14 |    6 | ri    |
| 18 |    5 | ls    |
| 13 |    5 | ta    |
|  7 |    4 | ta    |
|  5 |    4 | ni    |
|  6 |    3 | ni    |
|  4 |    3 | wo    |
|  2 |    2 | ni    |
|  1 |    2 | wo    |
+----+------+-------+
10 rows in set (0.04 sec)

mysql>
mysql> explain SELECT a.* FROM t a WHERE
    -> (
    -> SELECT COUNT(*) FROM t b WHERE a.g_id = b.g_id AND b.id<a.id
    -> ) < 2 ORDER BY a.g_id DESC\G
*************************** 1. row ***************************
           id: 1
  select_type: PRIMARY
        table: a
         type: index
possible_keys: NULL
          key: f_g_id
      key_len: 4
          ref: NULL
         rows: 25
        Extra: Using where
*************************** 2. row ***************************
           id: 2
  select_type: DEPENDENT SUBQUERY
        table: b
         type: ref
possible_keys: PRIMARY,f_g_id
          key: f_g_id
      key_len: 4
          ref: test.a.g_id
         rows: 2
        Extra: Using where; Using index
2 rows in set (0.00 sec)

使用道具 举报

回复
论坛徽章:
40
生肖徽章2007版:马
日期:2008-04-07 19:43:48管理团队成员
日期:2011-05-07 01:45:082012新春纪念徽章
日期:2012-02-13 15:08:092012新春纪念徽章
日期:2012-02-13 15:08:092012新春纪念徽章
日期:2012-02-13 15:08:092012新春纪念徽章
日期:2012-02-13 15:08:092012新春纪念徽章
日期:2012-02-13 15:08:09马上有车
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14
15#
发表于 2008-1-16 14:35 | 只看该作者
写了 一个。数据太少。看不出来效率如何。

  1. DELIMITER $$

  2. DROP PROCEDURE IF EXISTS `test`.`sp_get_num_group`$$

  3. CREATE PROCEDURE `test`.`sp_get_num_group`(
  4. IN f_num int)
  5. BEGIN
  6.   -- The variable stands for totla number of the record.
  7.   declare cnt int default 0;
  8.   declare i int;
  9.   -- Create temp table to reserved the result.
  10.   create temporary table if not exists tmp select * from t where 1 = 0;
  11.   -- Get the total number of the group by record.
  12.   select count(*) from
  13.   (
  14.     select count(*) from t group by g_id order by null
  15.   ) T into cnt;
  16.   set i = 0;
  17.   while i < cnt
  18.   do
  19.     -- Get the real g_id one by one.
  20.     set @stmt = concat('select g_id from t group by g_id order by g_id desc limit ',i,',1 into @tmp_id');
  21.     prepare s1 from @stmt;
  22.     execute s1;
  23.     drop prepare s1;
  24.     set @stmt = '';
  25.     -- Get the needed data.
  26.     set @stmt = concat('insert into tmp select * from t where g_id = ',@tmp_id,' order by g_id desc limit ',f_num);
  27.     prepare s1 from @stmt;
  28.     execute s1;
  29.     drop prepare s1;
  30.     set @stmt = '';
  31.     set i = i + 1;
  32.   end while;
  33.   -- Get the record from temp table.
  34.   select * from tmp;
  35.   -- Drop temp table.
  36.   drop table tmp;
  37. END$$

  38. DELIMITER ;
复制代码

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表