› MySQL 5.5 Community Server
› MySQL 5.6 Community Server
› Percona Configuration Wizard
› XtraBackup 搭建主从复制
Great Sites on MySQL
› Percona
› MySQL Performance Blog
› Severalnines
推荐管理工具
› Sequel Pro
› phpMyAdmin
推荐书目
› MySQL Cookbook
MySQL 相关项目
› MariaDB
› Drizzle
参考文档
› http://mysql-python.sourceforge.net/MySQLdb.html
enenaaa
V2EX  ›  MySQL

这样的需求,一条 sql 语句没法搞定吧

  •  
  •   enenaaa · Dec 8, 2016 · 5247 views
    This topic created in 3622 days ago, the information mentioned may be changed or developed.

    有这样一个表

    
    |id|logtime|
    |----| ----|
    | 1 | 5 |
    | 2 | 6 |
    | 3 | 6 |
    | 4 | 8 |
    | 5 | 8 |
    

    现在需要按 logtime 分组查询,每行求 logtime 小于等于当前值的 id 数。 例如 logtime=8 这行,求 logtime <= 8 的 count(id) 值。 最终结果是这样:

    
    |count|logtime|
    |----|----|
    | 1 | 5 |
    | 3 | 6 |
    | 5 | 8 |
    
    

    在一条 sql 语句内完成整表查询,不能用存储过程,不能用临时表,表变量,存储函数。 按我的理解,数据库查询是每行扫描一次。这个查询里一行需要重复扫描多次,应该是没法一次搞定的。 诸位有何良策。

    14 replies  •  2016-12-09 13:49:34 +08:00
    sagaxu
    sagaxu
    Dec 8, 2016 via Android
    1
    select logtime,count(*) as cnt from t group by logtime order by logtime

    然后业务代码里,对 cnt 值进行迭代累加,遍历一次即可,业务代码算法复杂度 O(n)
    F281M6Dh8DXpD1g2
    F281M6Dh8DXpD1g2
    Dec 8, 2016
    2
    不用 mysql 就行了
    sgzhan
    sgzhan
    Dec 8, 2016
    3
    为什么不能
    select logtime, count(id) as cnt from t where id<=logtime group by logtime 不就符合你的需求么?
    enenaaa
    enenaaa
    OP
    Dec 8, 2016
    4
    @sgzhan id 和 logtime 之间没有对应联系。 而且你这个语句也不对, group by 是用 logtime 分组,不包含小于当前值的行
    akira
    akira
    Dec 8, 2016❤️1
    5
    select count(1) `count` ,b.logtime from test ,
    (
    select distinct logtime from test
    )b
    where test.logtime <= b.logtime
    group by b.logtime
    order by b.logtime
    weizhiyao008
    weizhiyao008
    Dec 8, 2016❤️1
    6
    mssql
    ```
    select b.logtime,(select count(id) from table1 a where a.logtime <= b.logtime) as logcount
    from table1 b
    group by b.logtime
    ```
    weizhiyao008
    weizhiyao008
    Dec 8, 2016
    7
    @weizhiyao008 忘记看节点了, mysql 。。逃。。
    iEverX
    iEverX
    Dec 8, 2016❤️1
    8
    SELECT
    COUNT(1) AS cnt, a.logtime
    FROM
    (SELECT DISTINCT
    logtime
    FROM
    my) a
    JOIN
    my b ON a.logtime >= b.logtime
    GROUP BY a.logtime;
    TaMud
    TaMud
    Dec 8, 2016
    9
    3 楼正解
    多表统计也可以使用 3 楼的方法
    非常方便
    Aksura
    Aksura
    Dec 8, 2016
    10
    5 楼才是正解, 3 楼的不符合题意。
    enenaaa
    enenaaa
    OP
    Dec 8, 2016
    11
    @akira
    @weizhiyao008
    @iEverX
    谢谢, 你们思路是对的。我想歪了
    tusj
    tusj
    Dec 9, 2016
    12
    我在想, 如果表很大, 这种 join 加 group by 的写法会不会很耗资源和时间?
    如果楼主手上有数据可以对比一下, 看看在 logtime 是索引的情况下, 哪种快些.

    use test;
    drop table if exists test;
    create table test (id bigint, logtime bigint);
    insert into test values (1, 5);
    insert into test values (2, 6);
    insert into test values (3, 6);
    insert into test values (4, 8);
    insert into test values (5, 8);
    commit;

    -- 楼上各位的写法
    SELECT COUNT(1) le_count, b.logtime
    FROM test,
    (
    SELECT DISTINCT logtime
    FROM test
    ) b
    WHERE test.logtime <= b.logtime
    GROUP BY b.logtime
    ORDER BY b.logtime

    -- 我的写法
    SELECT (
    SELECT COUNT(1)
    FROM test t
    WHERE t.logtime <= a.logtime) as le_count, a.logtime
    FROM (
    SELECT DISTINCT logtime
    FROM test) a;
    enenaaa
    enenaaa
    OP
    Dec 9, 2016
    13
    @tusj 我的看法,排除掉索引的影响,没有本质区别。 这几种写法都是转换成了 join ,运算复杂度都是 n*n 级别。
    tusj
    tusj
    Dec 9, 2016
    14
    @enenaaa 执行计划不一样.
    你可以 explain 看一下.
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   4310 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 50ms · UTC 02:08 · PVG 10:08 · LAX 18:08 · JFK 21:08
    ♥ Do have faith in what you're doing.