sql取差集
⑴ 求助:sql取兩個查詢語句的差集
sqlserver是except
select*fromtawherecol1=xxx
except
select*fromtawherecol2=yyy;
oracle是minus
select*fromtawherecol1=xxx
minus
select*fromtawherecol2=yyy;
⑵ 求問:mysql如何查詢兩個欄位數不同的表中數據不一致的記錄
查詢兩張表數據不一致的記錄,可以用求差集(非交集)的辦法來解決。
SQL語言求"差集"的辦法相對於求"交集"的辦法要少很多,一般可用not exists(非存在子句)或 左(右)連接後所產生空欄位值來篩選兩表的差集。
下面舉個例子供參考
選出a表中與b表中id不一致的記錄
selecta.*fromawherenotexists(
select1frombwhereb.id=c.id);
說明:上述語句只比對id一個欄位,我們可以根據需要比對多個欄位。not exists在比對欄位有可利用的索引時,其運行效率是非常高,但是如果沒有索引的情況下運行在大數據表時,其運行效率極差,這時應避免使用它,這時我們可改用左(右)連接來求差集。
下面是用左連接來求差集的例子:
selecta.*fromaleftjoinbona.id=b.idwhereb.idisnull;
用左(右)連接來求差集,由於需要實施兩表連接會導致笛卡爾效應其輸出集的記錄行可能會增多,若果不是一對一或一對多,我們應該將多對多的情況處理成多對一後才進行連接,否則輸出的記錄集可能不正確。
求差集的兩種方法,有索引可利用時,not exists的效率要高於left join,反之left join效率更好。
⑶ 關於sql查詢b表中存在,a表中不存在的數據
這實際上是求非交集(差集)問題,sql語句求差集相對於求交集的辦法要少得多。
求差集方法中,使用not in關鍵字進行篩選在邏輯上最容易理解,很多人都會想到利用到它,數據量不大時還行,但是它有個重大缺陷,那就是在碰到大數據表的情況下其運行效率極低,有沒有可被利用的索引效率都一樣極差。我曾在利用大數據表的測試中,發現not in 語句常常要花費數小時才能返回結果,最誇張的例子耗時竟然超過一天!在返回結果前數據查詢會處在"假死"狀態,讓人感覺是返回了空集似的,其實不是那樣的,只是資料庫引擎尚未完成運算而已。
在有可被利用的索引情況下,我們可以利用非存在not exists子句來篩選出兩表之間的差集,其運行效率是非常高的。以題主的語句為例可改寫如下:
原來使用not in篩選差集,大數據表效率極差:
SELECT ipdz FROM ipdz_b WHERE ipdz not in(select ipdz_d from zj_b);
而使用not exists篩選差集,大數據表有索引可利用時返回結果酒快多了:
select b.ipdz from ipdz_b b where not exists(
select 1 from zj_b a where a.ipdz_d=b.ipdz);
請留意不要踩not exists的坑!盡管它在有可被利用的索引時運行效率極高,但是如果沒可利用的索引它會跟not in一樣在遇到大數據表時, 運行運行效率也很糟!
在沒有索引可被利用的情況下,建議利用左(右)聯接出現的null值來求出差集,但是需要留意並小心處理因兩表連接所導致的記錄行變多問題。
下面是以題主的表結構為例的sql語句寫法,其返回結果集的速度還是很不錯的:
left join 篩選差集:
select b.ipdz from ipdz_b b left join zj_b a on
a.ipdz_d=b.ipdz where a.ipdz_d is null;
這里假設a表的ipdz_d是唯一的,如果非唯一需調整如下
select b.ipdz from ipdz_b b left join (
select distinct ipzd_d from zj_b) a on
a.ipdz_d=b.ipdz where a.ipdz_d is null;
總結:
小數據量not in隨便用,此方法邏輯簡單,語句易於編寫;
大數據量在有可利用的索引情況下,建議首選 not exists(因為效率最高);
大數據量時,有沒有可被利用的索引not in都要避免使用。而not exists 在沒索引可利用時也應避免使用,此時建議使用左left join或右連接返回差集會有比較好的表現。
後兩種方法在邏輯上不太好理解,還要處理因連接導致的記錄行變多問題,語句編寫相對麻煩。
⑷ sql語句怎麼查兩個表布爾差集
sqlserver 是 except
select * from ta where col1 = xxxexceptselect * from ta where col2 = yyy;
oracle 是 minus
select * from ta where col1 = xxxminusselect * from ta where col2 = yyy;
⑸ plsql裡面兩個集合的合集,差集,交集怎麼寫
交集是兩個集合的公共元素,即兩個方程的公共解;
並集是兩個集合的元素的總個數(相同的元素只寫一次);
差集:如果兩個集合有交集,則大集元素中所有不屬於小集合的元素的集合是差集,如果沒有交集(空集),則A-B=A, B-A=B
⑹ 求高手給寫一條SQL語句,返回兩個表中的兩條數據之差
照你的需求來看,確定AB表都沒有DELETE吧?不然無意義。
首先為什麼不用資料庫自帶的自增序列,AB都共用一個自增序列,保證萬無一失。我估計你是不方便用或者是資料庫沒有。我倒是有個其他的辦法相對簡單點,就是建立一個public_id表假設叫C表,此表存放AB...所有表的自增最新ID,每次AB。。表插入都取C表的數據,這樣自增ID都出自同源,自然永遠相同。
要是比較AB表最大值,當他們數據激增的時候,光計算就得花很長時間,插入一條數據得等多長時間是無法估計得,更別提高並發了。
⑺ SQL集合查詢,20. 使用集合查詢列出CS系的學生與年齡不大於19歲的學生的交集、差集;
很高興回答你的問題
根據你的要求,改後SQL為:
selectsname,sage,decode(s,'1',sname)name,decode(s,'1',sage)agefrom(
selectsname,sage,sum(s)sfrom(
selectSname,Sage,'0'sfromstudentwhereSdept='CS'
union
selectSname,Sage,'0'sfromstudentwhereSage<=19
union
selectSname,Sage,'1'sfromstudentwhereSdept='CS'
minus
selectSname,Sage,'1'sfromstudentwhereSage<=19
)
groupbysname,sage)
該SQL是在ORACLE資料庫當中執行,當中的minus和你的except作用是一樣的,請看
效果圖(圖中數據為測試數據)
如有不懂請Hi我,扣我250267873都行
⑻ sql資料庫中把兩個表中的差集數據插入到第3個表,怎麼寫
insert into table_3 (column_1,column_2,column_3) select column_1,column_2,column_3 from table_1 minus select column_1,column_2,column_3 from table_2;
要點就是保持欄位一致。
⑼ SQL 語句 兩張表中的差集
我這么理解的你看是不是這個意思。
兩表數據也都是一樣的,主要看剩下的那200條
select * from tab1 where id not in (select id from tab2)
⑽ sql 查詢取差集,需要根據兩個欄位來確定行
你給的例子太特殊了,可以看成是不同的數字的差,也可以看成是求和後的差。
第一種,同意1樓,用EXCEPT最簡潔了
SELECT a, b from a except select a, b from b
第二種按照和來算
SELECT t1.a, SUM(t1.b) - SUM(t2.b)
FROM a t1
LEFT JOIN b t2
ON t1.a = t2. a
GROUP BY t1.a
最好可以對sum(t2.b)做一個null判斷,oracle裡面就是
SELECT t1.a, NVL(SUM(t1.b), 0) - NVL(SUM(t2.b), 0)
FROM a t1
LEFT JOIN b t2
ON t1.a = t2. a
GROUP BY t1.a
其他sql方言要對null判斷作適當轉換,類似
SELECT t1.a,
CASE WHEN SUM(t1.b) IS NULL THEN 0 ELSE SUM(t1.b) END
- CASE WHEN SUM(t2.b) IS NULL THEN 0 ELSE SUM(t2.b) END -
FROM a t1
LEFT JOIN b t2
ON t1.a = t2. a
GROUP BY t1.a