SQL not exists(select 1...

SQL篩選每個訂單(orderId)的時間(createTime)最早的那條記錄

select a.* from orders a where not exists  --將orders表命名爲a,下面一句又將orders表命名爲b;可看做將orders表複製了兩份,一份叫a,一份叫b
(select 1 from orders b  where b.orderId=a.orderId and b.createTime>a.createTime) --常規寫法是select b.orderId from ...,這裏寫成select 1 可以減少系統開銷,提升運行效率

/*
注意最終結果是從a中select的,所以not exists條件裏是b.createTime>a.createTime,
即當“a和b的orderId 相同時,b的createTime大於a的createTime”這種情況不存在,才保留a中的記錄
*/
  • 原理:

首先,需要明確、最外層的select是從表a中篩選,因此最後的結果是表a中篩出的數據。(後面的not exists 條件與這個大前提有關)
 

  • not exists

將主查詢的數據,放到子查詢中做條件驗證,根據驗證結果(TRUE 或 FALSE)來決定主查詢的數據結果是否得以保留。

exists : 強調的是是否返回結果集,不要求知道返回什麼, 只要exists引導的子句有結果集返回,那麼exists這個條件就算成立了

not exists:只要not exists引導的子句無結果返回,那麼此 not exists 條件成立,符合條件的該條數據得以保留

      exists(sql 返回結果集爲真)  
      not exists (sql 不返回結果集爲真)

 

  • select 1

select 1常搭配exists 當做條件使用,這裏的select和 select 任何一列  、select  * 的功能相同。select 1中的1是常量(當然也可以寫成select 0或select 2等等),select 1 from table 得到的結果每一行都是1,結果行數與table行數相等。

因爲和not exists搭配使用時,目地是判斷是否有存在,所以不需要返回任何字段信息。寫select 1比返回字段信息效率更高。


如果想同時用 where not exists 和 where... in ... ,

需要嵌套select,將  select... where ... in... 的結果看做一個新表,再從這個新表中用where not exists  進行select

select *  from (
select orderId,createTime,signid  from leasecontract where orderId in (11111,22222)
) a 
where not exists(select 1 from (
select orderId,createTime,signid  from leasecontract where orderId in(11111,22222))
) b  
where b.orderId=a.orderId and b.createTime>a.createTime) 
order by field(orderId,11111,22222)

/*
上面用到了select嵌套。
將 select orderId,createTime,signid  from leasecontract where orderId in (11111,22222) 得到的數據作爲一個新表
*/

 

 


2018-12-11日更新:

另一種方法(用max()方法選出時間最大的那條,作爲一個新表):
select * from table a where a.date in (select max(b.date) from table b where b.id=a.id)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章