二、實現方式
資料庫有重複的資料時,我們有時候需要取出時間最近的一條,來滿足業務場景。 下面介紹一下通過sql是怎麼實現的。
create
table
`t_iov_help_feedback`
(`id`
int(11)
notnull
auto_increment
comment
'主鍵id'
,`user_id`
int(
255)
default
null
comment
'使用者id'
,`problems`
varchar
(255
)default
null
comment
'問題描述'
,`last_updated_date`
datetime
default
null
comment
'最後更新時間'
,primary
key(
`id`))
engine
=innodb
default
charset
=utf8;
insert
into
`t_iov_help_feedback`
(`id`
,`user_id`
,`problems`
,`last_updated_date`
)values(1
,1,'時間比較小'
,'2021-02-23 10:11:49');
insert
into
`t_iov_help_feedback`
(`id`
,`user_id`
,`problems`
,`last_updated_date`
)values(2
,2,'時間小'
,'2021-02-23 10:12:49');
insert
into
`t_iov_help_feedback`
(`id`
,`user_id`
,`problems`
,`last_updated_date`
)values(3
,3,'我亂寫的'
,'2021-02-23 11:19:19');
insert
into
`t_iov_help_feedback`
(`id`
,`user_id`
,`problems`
,`last_updated_date`
)values(4
,1,'時間比較大'
,'2021-02-23 11:16:01');
insert
into
`t_iov_help_feedback`
(`id`
,`user_id`
,`problems`
,`last_updated_date`
)values(5
,2,'時間大'
可以看到,user_id為1和2都有重複資料。
user_id為1 時間最大的條記錄為 2021-02-23 11:16:01,user_id為2 時間最大的條記錄為 2021-02-23 11:19:13。
我們希望找到時間最大的這兩條記錄。
select
t1.重複列,
t1.時間列,
t1.其餘列
from
表 t1
inner
join
(select t2.重複列,
max( t2.時間列 )
as 時間列 from 表 t2 group
by t2.重複列 )
as t3
on t1.重複列 = t3.重複列 and t1.時間列 = t3.時間列
group
by t1.重複列
思想:1)先把該錶進行 group by 分組,並查詢出每組最大的時間列,得到乙個子表。
2)再將原本的表和子表通過重複列和時間列關聯起來;
這樣查詢出來的資料,都是以原表資料為準的,得到了時間最大的記錄的所有字段資訊。
3)但是如果最近的時間不止一條記錄,那麼就會出現重複,所以在外層還需要對原表進行group by去重。
1)mysql 5.7.5 以下版本sql實現:
-- mysql 5.7.5 以下版本
select
t1.user_id,
t1.last_updated_date,
t1.id,
t1.problems
from
t_iov_help_feedback t1
inner
join
(select t2.user_id,
max( t2.last_updated_date )
as last_updated_date from t_iov_help_feedback t2 group
by t2.user_id )
as t3
on t1.user_id = t3.user_id and t1.last_updated_date = t3.last_updated_date
group
by t1.user_id;
2)mysql 5.7.5 及以上版本 sql實現:
-- mysql 5.7.5 及以上版本
select
t1.user_id,
any_value(t1.last_updated_date)
as last_updated_date,
any_value(t1.id)
as id,
any_value(t1.problems)
as problems
from
t_iov_help_feedback t1
inner
join
(select t2.user_id,
max( t2.last_updated_date )
as last_updated_date from t_iov_help_feedback t2 group
by t2.user_id )
as t3
on t1.user_id = t3.user_id and t1.last_updated_date = t3.last_updated_date
group
by t1.user_id;
為什麼高版本和低版本的sql語句不一樣?
這是因為mysql 版本高於5.7.5時,預設設定的 sql_mode 模式是:only_full_group_by。如果沒有去除這個預設模式,又使用上述低版本的group by語句,會報以下錯誤:
mysql高版本,對報錯字段(非group by欄位)加了any_value()函式可以規避這個問題。
tips:any_value()會選擇被分到同一組的資料裡第一條資料的指定列值作為返回資料。
1)mysql 5.7.5 以下版本執行結果:
2)mysql 5.7.5 及以上版本執行結果:
可以看到,user_id為1和2的兩條記錄,都是取的時間比較近的那條資料。
這樣,就達到想要的效果啦~
刪除SQL表中重複的資料
第一步 將表中的資料放到乙個臨時表裡面 select identity int,1,1 as id,into temp from dianpingpoi where districtid 4313 and cuisineid 210 第二步 刪除臨時表裡面的重複資料 delete temp wher...
SQL中如何給列取別名?
在建立資料表時,一般都會使用英文單詞或英文單詞縮寫來設定欄位名,在查詢時列名都會以英文的形式顯示,這樣會給使用者檢視資料帶來不便。這只能怪情況可以使用別名來代替英文列名,增強閱讀性。建立別名可以通過用一下4中方法來實現 使用雙引號建立別名。如下 select goods name 商品名稱 from...
SQL 中如何拼寫時間型別
今天在作統計的時候,要在一使用者表中查詢出某一使用者的註冊時間,該欄位資料原型為 20030101 即為2003 01 01的意識,然後求出到該次查詢為止這一使用者的在網時間,因為db2中的date 函式只支援 date 2003 01 01 或date 01.01.2003 二種引數形式,所以不管...