mysql> select uid,max(b),count(*)
-> from a t1
-> where c=1
-> and b<=(select max(b) from a where uid=t1.uid and c=1)
-> and b>(select max(b) from a where uid=t1.uid and c=0)
-> group by uid
-> order by uid;
+------+--------+----------+
| uid | max(b) | count(*) |
+------+--------+----------+
| 1 | 7 | 4 |
| 2 | 7 | 2 |
| 3 | 7 | 4 |
+------+--------+----------+
3 rows in set (0.01 sec)
mysql>
uj5u.com熱心網友回復:
試過這陳述句,好慢,才幾萬條資料就運行卡主了
uj5u.com熱心網友回復:
樓主你這個表資訊不夠吧
既然你要求的是“最新”,那么表里必須要有個欄位標記記錄產生的先后次序
而一般在資料庫里,在查詢時如果不加上 order by 子句,查詢結果是不保證會按資料的實際生成時間排序的
如此一來,樓上幾位的查詢都無法保證結果是正確的
我的思路:
先找到 c = 0 的記錄中,最后出現的那一條,然后用它和原表進行比較,過濾掉比這條記錄還老的資料,再進行 count 計算
我在表里加了自增長欄位,用來比較一條記錄創建的先后次序,如果樓主的表里沒這類欄位,就當我沒說:
drop table if exists `t`;
create table `t`(
`id` int unsigned auto_increment,
`uid` int unsigned,
`b` int unsigned,
`c` int unsigned,
primary key(`id`)
);
insert into `t`(`uid`, `b`, `c`) values(1, 1, 1);
insert into `t`(`uid`, `b`, `c`) values(2, 1, 1);
insert into `t`(`uid`, `b`, `c`) values(3, 1, 1);
insert into `t`(`uid`, `b`, `c`) values(1, 2, 1);
insert into `t`(`uid`, `b`, `c`) values(2, 2, 1);
insert into `t`(`uid`, `b`, `c`) values(3, 2, 1);
insert into `t`(`uid`, `b`, `c`) values(1, 3, 0);
insert into `t`(`uid`, `b`, `c`) values(2, 3, 1);
insert into `t`(`uid`, `b`, `c`) values(3, 3, 0);
insert into `t`(`uid`, `b`, `c`) values(1, 4, 1);
insert into `t`(`uid`, `b`, `c`) values(2, 4, 0);
insert into `t`(`uid`, `b`, `c`) values(3, 4, 1);
insert into `t`(`uid`, `b`, `c`) values(1, 5, 1);
insert into `t`(`uid`, `b`, `c`) values(2, 5, 0);
insert into `t`(`uid`, `b`, `c`) values(3, 5, 1);
insert into `t`(`uid`, `b`, `c`) values(1, 6, 1);
insert into `t`(`uid`, `b`, `c`) values(2, 6, 1);
insert into `t`(`uid`, `b`, `c`) values(3, 6, 1);
insert into `t`(`uid`, `b`, `c`) values(1, 7, 1);
insert into `t`(`uid`, `b`, `c`) values(2, 7, 1);
insert into `t`(`uid`, `b`, `c`) values(3, 7, 1);
select * from t where uid = 3 order by id asc;
select t1.uid, max(t1.b) as B的最大值, count(t1.id) as 次數
from
t t1
left join (
select max(`id`) as max_zero_id, uid from `t` where c = 0 group by uid
) t2 on t1.uid = t2.uid
where
t1.id > t2.max_zero_id
group by uid;
SELECT uid,
MAX(b) as b,
SUM(c),
(SELECT SUM(t3.c) FROM "table" t3 WHERE t3.uid = t1.uid
and t3.b >= (SELECT max(b) as mb FROM "table" t2
WHERE c = 0 and t2.uid = t1.uid GROUP BY t2.uid)) as sum_c
FROM "table" t1
GROUP BY t1.uid ORDER BY t1.uid;
mysql> select count(*) from test;
+----------+
| count(*) |
+----------+
| 300000 |
+----------+
1 row in set (0.12 sec)
mysql> SELECT t1.uid,
-> SUM(`c`),
-> (SELECT SUM(t3.c) FROM `test` t3 WHERE t1.uid = t3.uid and t3.b >= t.mb) as c_sum
-> FROM `test` t1,
-> (SELECT t2.uid, max(b) as mb FROM `test` t2 WHERE t2.c=0 GROUP BY t2.uid) as t
-> WHERE t1.uid = t.uid
-> GROUP BY t1.uid ORDER BY t1.uid;
+------+----------+-------+
| uid | SUM(`c`) | c_sum |
+------+----------+-------+
| 1 | 99999 | 50000 |
| 2 | 99999 | 40000 |
| 3 | 99999 | 30000 |
+------+----------+-------+
3 rows in set (0.81 sec)
mysql>
uj5u.com熱心網友回復:
我是來灌水的
uj5u.com熱心網友回復:
select uid,max(b)-max(if(c=0,b,0)) as ct
from t
group by uid;
/*
uid ct
1 4
2 2
3 4
*/
uj5u.com熱心網友回復:
mysql 這樣也可以
select uid,max(b)-max((c=0)*b) as ct
from t
group by uid;
/*
uid ct
1 4
2 2
3 4
*/
SELECT a.uid ,MAX (b) b ,sum ( CASE WHEN b.id IS NULL THEN 0 ELSE 1 END ) FROM #aa a LEFT JOIN (
SELECT max (id) AS id ,uid FROM #aa WHERE c=0 GROUP BY uid
) b ON a.uid =b.uid AND a.id >b.id
GROUP BY a.uid
uj5u.com熱心網友回復:
忽略第二列,
CREATE TABLE #aa (id INT IDENTITY (1,1 ) , uid VARCHAR (50), b INT , c INT )
SELECT a.uid ,MAX (b) b ,sum ( CASE WHEN b.id IS NULL THEN 0 ELSE 1 END ) FROM #aa a LEFT JOIN (
SELECT max (id) AS id ,uid FROM #aa WHERE c=0 GROUP BY uid
) b ON a.uid =b.uid AND a.id >b.id
GROUP BY a.uid
你這看起來象是 sql server 的語法
并且,最后的查詢陳述句根本就不對,MAX(b) 是什么,left join 后面的子查詢,根本沒有 id 這個欄位
uj5u.com熱心網友回復:
是sql server 的語法,但原理一樣,如果你那不可以用臨時表,那就用這個
SELECT a.uid ,max (a.b) AS b , count (*) AS c FROM #aa a JOIN (
SELECT max (b) AS b ,uid FROM #aa WHERE c=0 GROUP BY uid
)b ON a.uid =b.uid AND a.b >b.b
GROUP BY a.uid
uj5u.com熱心網友回復:
是sql server 的語法,但原理一樣,如果你那不可以用臨時表,那就用這個
SELECT a.uid ,max (a.b) AS b , count (*) AS c FROM #aa a JOIN (
SELECT max (b) AS b ,uid FROM #aa WHERE c=0 GROUP BY uid
)b ON a.uid =b.uid AND a.b >b.b
GROUP BY a.uid
你的寫法和我的差不多(請看12樓)
思路就是,先找到每個 uid 最后一次出現的那條記錄作為一個子查詢,然后用這個子查詢作為依據對原表中的資料進行過濾,再count, group by。
因為資料庫的查詢在沒有寫 order by 子句的情況下,不保證每次查詢得到的結果集的記錄出現次序與記錄的寫入次序是一致的。但是我看樓主的意思里,并沒有哪個欄位可以用于判斷一條記錄產生的先后次序,所以給了個自增長的Id,雖然欄位 b 有這個規律,但樓主沒明說,所以我當它沒這個規則了。
uj5u.com熱心網友回復:
是sql server 的語法,但原理一樣,如果你那不可以用臨時表,那就用這個
SELECT a.uid ,max (a.b) AS b , count (*) AS c FROM #aa a JOIN (
SELECT max (b) AS b ,uid FROM #aa WHERE c=0 GROUP BY uid
)b ON a.uid =b.uid AND a.b >b.b
GROUP BY a.uid
你的寫法和我的差不多(請看12樓)
思路就是,先找到每個 uid 最后一次出現的那條記錄作為一個子查詢,然后用這個子查詢作為依據對原表中的資料進行過濾,再count, group by。
因為資料庫的查詢在沒有寫 order by 子句的情況下,不保證每次查詢得到的結果集的記錄出現次序與記錄的寫入次序是一致的。但是我看樓主的意思里,并沒有哪個欄位可以用于判斷一條記錄產生的先后次序,所以給了個自增長的Id,雖然欄位 b 有這個規律,但樓主沒明說,所以我當它沒這個規則了。
沒困難制造 困難要上,沒有ID 創制ID也要上 ,只是查詢,可以弄個臨時表,
uj5u.com熱心網友回復:
可以建一個狀態表保存各個uid連續1的次數
create table `a_status` (
`uid` INT NOT NULL,
`count_1` INT NOT NULL DEFAULT '0',
PRIMARY KEY (`uid`),
)
mysql> select uid,max(b),count(*)
-> from a t1
-> where c=1
-> and b<=(select max(b) from a where uid=t1.uid and c=1)
-> and b>(select max(b) from a where uid=t1.uid and c=0)
-> group by uid
-> order by uid;
+------+--------+----------+
| uid | max(b) | count(*) |
+------+--------+----------+
| 1 | 7 | 4 |
| 2 | 7 | 2 |
| 3 | 7 | 4 |
+------+--------+----------+
3 rows in set (0.01 sec)
mysql>
如果把資料1 7 1改為1 7 0查詢結果就不對了。
uj5u.com熱心網友回復:
占個位置學習一下
uj5u.com熱心網友回復:
sql:
select uid,concat(c) as str1 from a group by uid;
drop table if exists `t`;
create table `t`(
`id` int unsigned auto_increment,
`uid` int unsigned,
`b` int unsigned,
`c` int unsigned,
primary key(`id`)
);
insert into `t`(`uid`, `b`, `c`) values(1, 1, 1);
insert into `t`(`uid`, `b`, `c`) values(2, 1, 1);
insert into `t`(`uid`, `b`, `c`) values(3, 1, 1);
insert into `t`(`uid`, `b`, `c`) values(1, 2, 1);
insert into `t`(`uid`, `b`, `c`) values(2, 2, 1);
insert into `t`(`uid`, `b`, `c`) values(3, 2, 1);
insert into `t`(`uid`, `b`, `c`) values(1, 3, 0);
insert into `t`(`uid`, `b`, `c`) values(2, 3, 1);
insert into `t`(`uid`, `b`, `c`) values(3, 3, 0);
insert into `t`(`uid`, `b`, `c`) values(1, 4, 1);
insert into `t`(`uid`, `b`, `c`) values(2, 4, 0);
insert into `t`(`uid`, `b`, `c`) values(3, 4, 1);
insert into `t`(`uid`, `b`, `c`) values(1, 5, 1);
insert into `t`(`uid`, `b`, `c`) values(2, 5, 0);
insert into `t`(`uid`, `b`, `c`) values(3, 5, 1);
insert into `t`(`uid`, `b`, `c`) values(1, 6, 1);
insert into `t`(`uid`, `b`, `c`) values(2, 6, 1);
insert into `t`(`uid`, `b`, `c`) values(3, 6, 1);
insert into `t`(`uid`, `b`, `c`) values(1, 7, 0);
insert into `t`(`uid`, `b`, `c`) values(2, 7, 1);
insert into `t`(`uid`, `b`, `c`) values(3, 7, 0);
select t1.uid,t1.b-IFNULL(max(t.b),0)as ct
from
(select uid,max(b)b from t where c=1 group by uid)t1
left join t
on t.uid=t1.uid and t.c=0 and t.b<t1.b
group by t1.uid
/*
uid ct
1 3
2 2
3 3
*/
uj5u.com熱心網友回復:
select a.uid,count(1) from t a,(select uid,max(b) as b from t where c=0 group by uid) b where a.uid=b.uid and a.b>b.b group by a.uid;
uj5u.com熱心網友回復:
看不懂你的需求
uj5u.com熱心網友回復:
SELECT
t.uid,
MAX(t.b) AS b,
MAX(t.b) - MAX(r.max) AS last_b
FROM
`t`
JOIN
(SELECT
uid,
MAX(b) AS `max`
FROM
`t`
WHERE c = 0
GROUP BY uid) AS r ON r.uid = t.uid
WHERE t.c = 1
GROUP BY t.uid
uj5u.com熱心網友回復:
SELECT
t.uid,
MAX(t.b) AS b,
MAX(t.b) - MAX(r.max) AS last_b
FROM
`t`
JOIN
(SELECT
uid,
MAX(b) AS `max`
FROM
`t`
WHERE c = 0
GROUP BY uid) AS r ON r.uid = t.uid
WHERE t.c = 1
GROUP BY t.uid
uj5u.com熱心網友回復:
樓主是在做類似連續簽到的業務需求嗎
uj5u.com熱心網友回復:
看上這400分了
#EXPLAIN
SELECT
uid,
MAX(b) AS b,
POSITION(0 IN GROUP_CONCAT(c ORDER BY b DESC SEPARATOR ""))-1 AS num
FROM t
GROUP BY t.uid
+------+------+------+
| uid | b | num |
+------+------+------+
| 1 | 7 | 4 |
| 2 | 7 | 2 |
| 3 | 7 | 4 |
+------+------+------+
3 rows in set (0.00 sec)
MariaDB [test]> select count(*) from t;
+----------+
| count(*) |
+----------+
| 1200018 |
+----------+
1 row in set (0.34 sec)
MariaDB [test]> SELECT uid, MAX(b) AS b, POSITION(0 IN GROUP_CONCAT(c ORDER BY b DESC SEPARATOR ""))-1 AS num FROM t GROUP BY t.uid;
+------+--------+------+
| uid | b | num |
+------+--------+------+
| 1 | 400006 | 0 |
| 2 | 400006 | 0 |
| 3 | 400006 | 0 |
+------+--------+------+
3 rows in set (0.87 sec)
模擬資料生成方式
#創建存盤程序
CREATE PROCEDURE test_insert ()
#開始
BEGIN
#定義變數
DECLARE i INT DEFAULT 1;
DECLARE b INT DEFAULT 8;
#條件判斷
WHILE i<400000 #400000*3=1200000
#執行
DO
#SQL
INSERT INTO t(uid, b, c) VALUES
(1, b, FLOOR(RAND()*10%2)),
(2, b, FLOOR(RAND()*10%2)),
(3, b, FLOOR(RAND()*10%2));
#變數增加
SET i=i+1;
SET b=b+1;
#結束回圈
END WHILE ;
#提交
commit;
#結束
END;
#執行
CALL test_insert();
#洗掉存盤程序
drop procedure test_insert ;
uj5u.com熱心網友回復:
先加個自增id
select t1.uid, count(1) from t t1 where t1.c = 1 and t1.id > (
select max(t2.id) from t t2 where t2.uid = t1.uid and t2.c = 0
) group by t1.uid
uj5u.com熱心網友回復:
先加個自增id
select t1.uid, count(1) from t t1 where t1.c = 1 and t1.id > (
select max(t2.id) from t t2 where t2.uid = t1.uid and t2.c = 0
) group by t1.uid
資料量大的話,給uid和c加索引
uj5u.com熱心網友回復:
先加個自增id
select t1.uid, count(1) from t t1 where t1.c = 1 and t1.id > (
select max(t2.id) from t t2 where t2.uid = t1.uid and t2.c = 0
) group by t1.uid
資料量大的話,給uid和c加索引
上面那個有點慢,改了一下,十萬條資料,不加索引,100毫秒左右
select t1.uid, count(1) from t t1,
(select t2.uid, max(t2.id) id from t t2 where t2.c = 0 group by t2.uid) t3
where t1.c = 1 and t1.uid = t3.uid and t1.id > t3.id group by t1.uid
uj5u.com熱心網友回復:
先加個自增id
select t1.uid, count(1) from t t1 where t1.c = 1 and t1.id > (
select max(t2.id) from t t2 where t2.uid = t1.uid and t2.c = 0
) group by t1.uid
資料量大的話,給uid和c加索引
上面那個有點慢,改了一下,十萬條資料,不加索引,100毫秒左右
select t1.uid, count(1) from t t1,
(select t2.uid, max(t2.id) id from t t2 where t2.c = 0 group by t2.uid) t3
where t1.c = 1 and t1.uid = t3.uid and t1.id > t3.id group by t1.uid
再考慮c=0不存在的情況,加個左連接,完美!
select t1.uid, count(1) from t t1
left join (select t2.uid, max(t2.id) id from t t2 where t2.c = 0 group by t2.uid) t3 on t1.uid = t3.uid
where t1.c = 1 and t1.id > ifnull(t3.id,0) group by t1.uid
uj5u.com熱心網友回復:
接分 我一點分都沒有了,給點分我吧
uj5u.com熱心網友回復:
可以可以,學到了。
uj5u.com熱心網友回復:
select uid,max(b) as b,LOCATE(0,REVERSE(REPLACE(GROUP_CONCAT(c order by b),',','')))-1 as s from a group by uid ORDER BY b
**桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......
我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......
關于MySQL的二進制日志(binlog),我們都知道二進制日志(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關于二進制日志(binlog)的備份,可以基于flush logs方式先切換binlog,然后拷貝&壓縮到到遠程服務器或本地服務器 ......