2016年2月4日 星期四

比對兩筆資料


比對兩資料表A有B沒有

一、
SELECT A.TR1001
FROM R01 A
WHERE A.TR1001 NOT 
IN (
SELECT B.TR2001
FROM R02 B


二、
select A.TR1001,A.TR1002 from (select * from R01 A LEFT JOIN R02 B ON A.TR1001 = B.TR2001)
WHERE B.TR2001 IS NULL


第一種較耗系統資源
第二種較佳


SELECT TR1001 FROM R01
MINUS
SELECT TR1002 FROM R02


-------------------------------------------------------


刪除重複資料

今天又遇到一個問題,有個髒髒的資料庫,裡面有很多筆重複的資料
例如
image
要篩選出資料但不重複很簡單,就 Select distinct 欄位 from Table名稱 就行了
image
可以看到實際上的資料只有四筆,假設這張table沒有跟其他的table有關連
那我要如何刪掉重複的資料只保留一筆呢?
先試著留下一筆資料
  Select * From [Product] Where ID In (Select Max(ID) From [Product] Group By 產品名稱)

image



應該很直覺吧,就是先將資料Group by一個重複的欄位,然後篩出主索引鍵
然後用原table where in 這些資料,就可以篩出來了。
刪除的話,就是顛倒條件
  DELETE Product where ID NOT IN (Select Max(ID) From [Product] Group By 產品名稱)

就行囉。
image

小提醒:刪除資料前最好先簡單備份一下比較保險喔
快速語法  SELECT *  INTO   新的table名  FROM   來源table

假設今天這table連主索引鍵都沒有。如這樣
image
怎辦呢? 沒差,利用ROW_NUMBER() + CTE 創一個欄位給他就行了
with temp as(
SELECT *, ROW_NUMBER() over(order by 產品名稱) as rnk
FROM [MY].[dbo].[Product]
)
  
select * from temp 
where rnk IN
(SELECT Max(rnk) FROM temp GROUP BY 產品名稱)

image

刪除就是把第6行~第8行的SELECT換成
DELETE temp where rnk NOT IN (Select Max(rnk) From temp Group By 產品名稱)

就行啦。

再假設今天的Table雖然有重複資料,但不是每個欄位的資料都重複,如
image
那我想只想留同一品名價格最大的話
一樣是
with temp as(
SELECT *, ROW_NUMBER() over(order by 單價) as rnk
FROM [MY].[dbo].[Product]
)
  
select * from temp 
where rnk IN
(SELECT Max(rnk) FROM temp  GROUP BY 產品名稱) 

image
刪除就跟上面的寫法一樣囉。

心得:CTE真好用 :)

PLSQL - 使用 MINUS 與 INTERSECT 來比對兩個資料表中的資料

在<SQL - 使用 EXCEPT 與 INTERSECT 來比對兩個資料表中的資料>這篇講到,如何使用 MS SQL 提供的 EXCEPT 與 INTERSECT 來比對兩個資料表中的資料。那麼在 Oracle 中,是否有提供這樣的指令呢!? 答案是有的,那就是「MINUS」與「INTERSECT」,其中「INTERSECT」這個指令還真眼熟,其功能與MS SQL是一樣的,而另外一個「MINUS」是與「EXCEPT」功能相同的,以下還是用一個簡單的範例來實作看看嚕...

步驟一:建立兩個名為「DC_TEST_1」與「DC_TEST_2」的資料表

資料表名稱:DC_TEST_1
欄位:U_NO(number)、USER_NAME(varchar(20))

資料表名稱:DC_TEST_2
欄位:U_NO(number)、USER_NAME(varchar(20))

步驟二:各別新增資料

資料表名稱:DC_TEST_1

Insert ALL
into dcms.dc_test_1(U_NO, USER_NAME) values(1, 'Danny_Chang_1')
into dcms.dc_test_1(U_NO, USER_NAME) values(2, 'Danny_Chang_2')
into dcms.dc_test_1(U_NO, USER_NAME) values(3, 'Danny_Chang_3')
into dcms.dc_test_1(U_NO, USER_NAME) values(4, 'Danny_Chang_4')
into dcms.dc_test_1(U_NO, USER_NAME) values(5, 'Danny_Chang_5')
SELECT * FROM DUAL;

資料表名稱:DC_TEST_2

Insert ALL
into dcms.dc_test_2 values(1, 'Danny_Chang_1')
into dcms.dc_test_2 values(4, 'Danny_Chang_4')
into dcms.dc_test_2 values(5, 'Danny_Chang_5')
SELECT * FROM DUAL;

步驟三:使用 MINUS 與 INTERSECT 來比對兩個資料表中的資料

MINUS:

Select * From dcms.dc_test_1
MINUS
Select * From dcms.dc_test_2;



INTERSECT:

Select * From dcms.dc_test_1
INTERSECT
Select * From dcms.dc_test_2;



參考:
The UNION [ALL], INTERSECT, MINUS Operators
Oracle Insert Statements

--------------------------------------------------------

2張資料表,要比對缺了哪幾筆

https://dotblogs.com.tw/mis0800/2014/01/22/142046
◆2張資料表,要比對缺了哪幾筆
OM01
A


OM02
B

1、
select Table_1.a1 from (select a from OM01 A LEFT
JOIN OM02 B  ON A.OM1001 = B.OM2001)
WHERE B.OM2001 IS NULL

2、
SELECT A.OM1001  FROM OM01 A
WHERE A.OM1001 NOT IN (
SELECT B.OM2001 FROM OM02 B)


EX:
Table_1
a1

Table_6
a

SELECT a1 FROM Table_1
WHERE a1 NOT IN (
SELECT a FROM Table_6)

SELECT a FROM Table_6
WHERE a NOT IN (
SELECT a1 FROM Table_1
)
--------------------------------------------------------------

兩個資料表的值互相比較取值


http://idlemanhome.blogspot.tw/2013/10/ms-sql.html
偶爾會用到,當要尋找兩個(或以上)不同資料表之間,有相同的兩個以上的值需互相比較,找出符合條件的結果之時。
有需要用到 別名Alias
SELECT t1.Value_a1, t1.Value_a2 
  FROM ( SELECT [Value_a1], [Value_a2] FROM [Table1] WHERE [ID]=123 ) AS t1,
       ( SELECT [Value_b1], [Value_b2] FROM [Table2] WHERE [ID]=456 ) AS t2
 WHERE t1.Value_a1 <= t2.Value_b1 and t1.Value_a2 <= t2.Value_b2;






沒有留言: