先看mysql乙個簡單的變數查詢:
set @rownum = 0;
select ( @rownum := @rownum + 1 ) as ranknum;
變數初始值rownum設定為0,查詢一行資料變數+1,定義為排行號,也是資料行號
現在簽到表結構如下:
create table `sign_in` (
`phone` varchar(11) not null comment '登入手機號',
`integral_num` decimal(3,0) not null default '0' comment '簽到獲取的積分',
`create_time` timestamp not null default current_timestamp comment '簽到時間',
key `sign_in_phone` (`phone`) using btree,
key `sign_in_create_time` (`create_time`) using btree
) engine=innodb default charset=utf8mb4 comment='簽到表';
1、要查詢累計簽到天數排行前10,查詢sql如下:
set @rownum = 0;
select
( @rownum := @rownum + 1 ) as rowno,
t.phone,
t.count
from
( select phone, count( 1 ) as count from sign_in group by phone order by count desc limit 10 ) t;
set @rownum = 0;
select
tt.rowno,
tt.phone,
tt.count
from
( select
( @rownum := @rownum + 1 ) as rowno,
t.phone,
t.count
from
( select phone, count( 1 ) as count from sign_in group by phone order by count desc ) t
) tt
where
tt.phone = '***';
還是上面的簽到表,統計乙個人連續簽到天數
select
count( 1 )
from
( select
date_sub( a.create_time, interval 1 day ) signdate,
( @i := date_sub( @i, interval 1 day ) ) today
from
( select create_time from sign_in where phone = '33' order by create_time desc ) a
inner join (
select
@i := max( create_time ) as signmax
from
sign_in
where
phone = '33'
and (
to_days( create_time ) = to_days( curdate( ) )
or to_days( create_time ) = to_days( date_sub( curdate( ), interval 1 day ) )
) ) b
where
b.signmax is not null
and to_days(@i) = to_days(a.create_time)
) c
分析一下查詢邏輯:
1、第一句要從這裡說起 ,查詢手機號33的人的簽到時間倒敘集合
select create_time from sign_in where phone = '33' order by create_time desc2、第二部分就是聯合變數,查詢的最後一次簽到時間
select條件是簽到時間是今天或者昨天的時間,選出乙個最近的,也是最大的,這個結果有三種:今天,昨天,或者空@i := max( create_time ) as signmax
from
sign_in
where
phone = '33'
and (
to_days( create_time ) = to_days( curdate( ) )
or to_days( create_time ) = to_days( date_sub( curdate( ), interval 1 day ) )
)
3、然後前兩部分內容聯合之後,查詢兩個日期,乙個簽到時間,第二個是變數記錄的時間
select這兩個日期時間都減去了一天,這是為了要記錄日期的變數「變化」,要讓變數隨著每一行資料一天一天變化,可以保證這個變數日期是連續的。date_sub( a.create_time, interval 1 day ) signdate,
( @i := date_sub( @i, interval 1 day ) ) today
from
第乙個簽到日期也減一天,這是為了匹配當天簽到時候和變數保持一致,不然會丟一天
4、最後一部分就是where條件裡的限制
b.signmax is not null上面2部分說的可能是空,空標識斷籤了,不管從哪天斷的查出來都是0,所以第乙個條件就是這個引數不為空and to_days(@i) = to_days(a.create_time)
第二個條件就是兩個日期時間要相等,參照的就是變數日期是一天一天減下來的,和它相等的才是連續簽到的,只要不連續的都會往前排導致日期不匹配被過濾掉。
mysql查詢排行榜 mysql 查詢排名
sql語句查詢排名 思路 有點類似迴圈裡面的自增一樣,設定乙個變數並賦予初始值,迴圈一次自增加1,從而實現排序 mysql裡則是需要先將資料查詢出來並先行按照需要排序的字段做好降序desc,或則公升序asc,設定好排序的變數 初始值為0 a 將已經排序好的資料從第一條依次取出來,取一條就自增加一,實...
mysql計數 mysql實現計數器
本文 如果是在非常高的併發之下,還是建議用記憶體資料庫redis去實現計數的功能。如果不是那麼高的併發,用表實現就可以。drop table access counter create table access counter cnt int unsigned not null insert int...
mysql製作排行榜 mysql實現排行榜
博主新人一枚,大家可以提出自己的寶貴意見。下來我們進入正題。大家首先要了解介面的場景,再就是排行榜的規則,我們這裡說的中國式排行榜。排行榜總結了一下分為3種 中國式排行 非中國式排行1 非中國式排行2 1 1 1 2 2 2 2 2 3 3 4 4 3 5 5 4 5 6 5 7 7 select ...