none
請問各位大大有關2個TABLE做Join後是否能做部分的資料保留(即如何刪除部分重複資料) RRS feed

  • 問題

  • 請問各位大大:

         將兩個TABLE 即TABLE1 與 TABLE 2 做Join 產生TABLE 3

    TABLE 1是客戶檔 (包含客戶名稱及料號),TABLE 2 是產品檔(如下圖1)  TABLE 3 是做left join的結果(如圖二)

    問題是我要將TABLE 3 重複的資料部分(即框起來的部分)做刪除動作 請問我該如何處理呢(是在查詢結果時比較前後筆的資料欄位是否相同時刪除嗎?)

    請問各位大大程式碼該如何寫呢?

    感謝各位大大

    2015年3月5日 上午 06:26

解答

  • 您好,
    請參考「重複的欄位值,第1筆資料後的資料顯示空白

    USE tempdb
    GO
    -- drop table t1;
    CREATE TABLE t1(
    	[月底] DATE,
    	[異動日] DATE,
    	[客戶] VARCHAR(10),
    	[料號] VARCHAR(30),
    	[品名] VARCHAR(30),
    	[規格] VARCHAR(30),
    	[單位名稱] VARCHAR(10),
    	[庫存數量] INT ,
    	[成本] INT
    );
    GO
    
    INSERT INTO dbo.t1( 月底, 異動日, 客戶, 料號, 品名, 規格, 單位名稱, 庫存數量, 成本 )
    VALUES  ('2015/02/28', -- 月底 - date
              '2012/07/31', -- 異動日 - date
              'A', -- 客戶 - varchar(10)
              'A003001374', -- 料號 - varchar(30)
              '#7745FL', -- 品名 - varchar(30)
              '1372mm*508M', -- 規格 - varchar(30)
              'a', -- 單位名稱 - varchar(10)
              1, -- 庫存數量 - int
              0  -- 成本 - int
              );
    
    INSERT INTO dbo.t1( 月底, 異動日, 客戶, 料號, 品名, 規格, 單位名稱, 庫存數量, 成本 )
    VALUES  ('2015/02/28', -- 月底 - date
              '2012/2/11', -- 異動日 - date
              'A', -- 客戶 - varchar(10)
              'XFT120723A10', -- 料號 - varchar(30)
              '##7952MP', -- 品名 - varchar(30)
              '610mm*914mm', -- 規格 - varchar(30)
              'a', -- 單位名稱 - varchar(10)
              38, -- 庫存數量 - int
              7953  -- 成本 - int
              );
    INSERT INTO dbo.t1( 月底, 異動日, 客戶, 料號, 品名, 規格, 單位名稱, 庫存數量, 成本 )
     VALUES  ('2015/02/28', -- 月底 - date
              '2015/1/12', -- 異動日 - date
              'L', -- 客戶 - varchar(10)
              'XAT131022A10', -- 料號 - varchar(30)
              '#M 8020P', -- 品名 - varchar(30)
              '610mm*914mm', -- 規格 - varchar(30)
              'a', -- 單位名稱 - varchar(10)
              38, -- 庫存數量 - int
              7953  -- 成本 - int
              );
    INSERT INTO dbo.t1( 月底, 異動日, 客戶, 料號, 品名, 規格, 單位名稱, 庫存數量, 成本 )
     VALUES  ('2015/02/28', -- 月底 - date
              '2015/1/12', -- 異動日 - date
              'K', -- 客戶 - varchar(10)
              'XAT131022A10', -- 料號 - varchar(30)
              '#M 8020P', -- 品名 - varchar(30)
              '610mm*914mm', -- 規格 - varchar(30)
              'a', -- 單位名稱 - varchar(10)
              38, -- 庫存數量 - int
              7953  -- 成本 - int
              );
    INSERT INTO dbo.t1( 月底, 異動日, 客戶, 料號, 品名, 規格, 單位名稱, 庫存數量, 成本 )
     VALUES  ('2015/02/28', -- 月底 - date
              '2015/1/12', -- 異動日 - date
              'j', -- 客戶 - varchar(10)
              'XAT131022A10', -- 料號 - varchar(30)
              '#M 8020P', -- 品名 - varchar(30)
              '610mm*914mm', -- 規格 - varchar(30)
              'a', -- 單位名稱 - varchar(10)
              38, -- 庫存數量 - int
              7953  -- 成本 - int
              );
    
    SELECT *
    FROM (
    SELECT rn=ROW_NUMBER() OVER(PARTITION BY [規格] , [單位名稱], [庫存數量], [成本] ORDER BY  [規格] )
    , *
     FROM t1) tabA
     WHERE tabA.rn = 1;
      


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/


    • 已編輯 亂馬客 2015年3月5日 下午 12:52
    • 已標示為解答 MichaelTsai10 2015年3月6日 上午 02:09
    2015年3月5日 下午 12:50

所有回覆

  • 不太懂 你 客戶 E,F,G,H,I,J,K,L 沒有買 XAT131022A10嗎?
    你兩張表是用哪一個欄位去關聯的?!

    感覺你應該會有一張 客戶 跟 產品的關聯表去記錄 哪個客戶買了哪個產品(多對多的表)。

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

    如果你只是想要 看到

    你應該只要把table2 當主表 left join table1 應該就是你要的結果了。

    select table1.* ,table2.* from table2 left join table1 on (...關聯..)


    2015年3月5日 上午 06:34
  • 親愛的大大你好:

         因為一次只能貼兩張圖圖的內容如下

    就是客戶購買的產品及料號 內有客戶名稱及料號


        

    現在因為需求單位希望在資料庫中撈

    那些料號是客戶曾經買過的然後要得到如下的結果,也就是規格 單位名稱 庫存數量 平均成本 庫存成本 呆滯月份這幾欄 伊甸與前一筆資料相同就刪除

    請問各位大大有辦法做到嗎? 謝謝

    2015年3月5日 上午 06:54
  • 所以你的問題是 "哪些產品至少被一個客戶買過?!"

    select * from table2 where 料號 in (select distinct 料號 from table1)

    2015年3月5日 上午 07:17
  • 大大你好:

        我是從出貨單去查詢哪些客戶買過那些料號

       原始程式碼如下:

    SELECT     ad.公司簡稱, AC.料號  
    FROM         (SELECT DISTINCT aa.客戶代號, ab.料號   FROM          出貨單 AS aa INNER JOIN
    出貨細目 AS ab ON aa.出貨單號 = ab.出貨單號  WHERE      (ab.料號 LIKE 'X%')  GROUP BY aa.客戶代號, ab.料號) AS AC INNER JOIN
    (SELECT     客戶代號, 公司簡稱   FROM     客戶) AS ad ON AC.客戶代號 = ad.客戶代號  GROUP BY ad.公司簡稱, AC.料號
     ORDER BY AC.料號, ad.公司簡稱

    最後會得到 那些公司買過那些料號

    也就是相同的料號可能被多家公司買過

    但我們只求X開頭的料號

    2015年3月5日 上午 07:29
  • 大大你好:

        我是從出貨單去查詢哪些客戶買過那些料號

       原始程式碼如下:

    SELECT     ad.公司簡稱, AC.料號  
    FROM         (SELECT DISTINCT aa.客戶代號, ab.料號   FROM          出貨單 AS aa INNER JOIN
    出貨細目 AS ab ON aa.出貨單號 = ab.出貨單號  WHERE      (ab.料號 LIKE 'X%')  GROUP BY aa.客戶代號, ab.料號) AS AC INNER JOIN
    (SELECT     客戶代號, 公司簡稱   FROM     客戶) AS ad ON AC.客戶代號 = ad.客戶代號  GROUP BY ad.公司簡稱, AC.料號
     ORDER BY AC.料號, ad.公司簡稱

    最後會得到 那些公司買過那些料號

    也就是相同的料號可能被多家公司買過

    但我們只求X開頭的料號


    最後面 where ac.料號 like 'X%'
    沒有效果?!
    2015年3月5日 上午 08:05
  • 報告大大:

       'X%'有效果 但現在我們是要把產品重複的部分資料刪除也就是不要重複出現以免使用單位弄錯

    謝謝

    2015年3月5日 上午 08:09
  • 這類條件應該要配合訂單單號或出貨單單號來做 JOIN ,否則你在做 客戶購買的產品及料號 的子查詢時,就要先用 DISTINCT 把條件過濾掉。

    你可以參考這篇:[SQL] Join 的 WHERE 條件式位置

    的法 3 來處理子查詢內有 DISTINCT 的查詢,及上面的 X% ,透過子查詢先過濾掉資料後,再做 JOIN 可以節省 3 次方的運算時間。


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    2015年3月5日 上午 11:52
  • 您好,
    請參考「重複的欄位值,第1筆資料後的資料顯示空白

    USE tempdb
    GO
    -- drop table t1;
    CREATE TABLE t1(
    	[月底] DATE,
    	[異動日] DATE,
    	[客戶] VARCHAR(10),
    	[料號] VARCHAR(30),
    	[品名] VARCHAR(30),
    	[規格] VARCHAR(30),
    	[單位名稱] VARCHAR(10),
    	[庫存數量] INT ,
    	[成本] INT
    );
    GO
    
    INSERT INTO dbo.t1( 月底, 異動日, 客戶, 料號, 品名, 規格, 單位名稱, 庫存數量, 成本 )
    VALUES  ('2015/02/28', -- 月底 - date
              '2012/07/31', -- 異動日 - date
              'A', -- 客戶 - varchar(10)
              'A003001374', -- 料號 - varchar(30)
              '#7745FL', -- 品名 - varchar(30)
              '1372mm*508M', -- 規格 - varchar(30)
              'a', -- 單位名稱 - varchar(10)
              1, -- 庫存數量 - int
              0  -- 成本 - int
              );
    
    INSERT INTO dbo.t1( 月底, 異動日, 客戶, 料號, 品名, 規格, 單位名稱, 庫存數量, 成本 )
    VALUES  ('2015/02/28', -- 月底 - date
              '2012/2/11', -- 異動日 - date
              'A', -- 客戶 - varchar(10)
              'XFT120723A10', -- 料號 - varchar(30)
              '##7952MP', -- 品名 - varchar(30)
              '610mm*914mm', -- 規格 - varchar(30)
              'a', -- 單位名稱 - varchar(10)
              38, -- 庫存數量 - int
              7953  -- 成本 - int
              );
    INSERT INTO dbo.t1( 月底, 異動日, 客戶, 料號, 品名, 規格, 單位名稱, 庫存數量, 成本 )
     VALUES  ('2015/02/28', -- 月底 - date
              '2015/1/12', -- 異動日 - date
              'L', -- 客戶 - varchar(10)
              'XAT131022A10', -- 料號 - varchar(30)
              '#M 8020P', -- 品名 - varchar(30)
              '610mm*914mm', -- 規格 - varchar(30)
              'a', -- 單位名稱 - varchar(10)
              38, -- 庫存數量 - int
              7953  -- 成本 - int
              );
    INSERT INTO dbo.t1( 月底, 異動日, 客戶, 料號, 品名, 規格, 單位名稱, 庫存數量, 成本 )
     VALUES  ('2015/02/28', -- 月底 - date
              '2015/1/12', -- 異動日 - date
              'K', -- 客戶 - varchar(10)
              'XAT131022A10', -- 料號 - varchar(30)
              '#M 8020P', -- 品名 - varchar(30)
              '610mm*914mm', -- 規格 - varchar(30)
              'a', -- 單位名稱 - varchar(10)
              38, -- 庫存數量 - int
              7953  -- 成本 - int
              );
    INSERT INTO dbo.t1( 月底, 異動日, 客戶, 料號, 品名, 規格, 單位名稱, 庫存數量, 成本 )
     VALUES  ('2015/02/28', -- 月底 - date
              '2015/1/12', -- 異動日 - date
              'j', -- 客戶 - varchar(10)
              'XAT131022A10', -- 料號 - varchar(30)
              '#M 8020P', -- 品名 - varchar(30)
              '610mm*914mm', -- 規格 - varchar(30)
              'a', -- 單位名稱 - varchar(10)
              38, -- 庫存數量 - int
              7953  -- 成本 - int
              );
    
    SELECT *
    FROM (
    SELECT rn=ROW_NUMBER() OVER(PARTITION BY [規格] , [單位名稱], [庫存數量], [成本] ORDER BY  [規格] )
    , *
     FROM t1) tabA
     WHERE tabA.rn = 1;
      


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/


    • 已編輯 亂馬客 2015年3月5日 下午 12:52
    • 已標示為解答 MichaelTsai10 2015年3月6日 上午 02:09
    2015年3月5日 下午 12:50
  • 請教大大:

      依據您的指教清除了 料號,品名,規格,單位名稱,庫存數量,平均成本,庫存成本

    但由於呆滯月份不同無法清除

    請問有無方法判斷當料號為空白時呆滯月份為空白

    請各位大大指教

    2015年3月7日 下午 05:09
  • 用Case when吧

    Case 料號 when '' then ''

    else 呆滯月份

    end as 呆滯月份

    2015年3月8日 上午 01:07
  • 您好,
    您要的是要刪除那些 rn 大於 1 的資料吧!

    一般來說 table 會有 PK,所以我在原本的欄位中加入 pk 這個欄位。

    然後找出那些 rn > 1 的,再將它們刪除掉,不需要理會其他的欄位不同。如下,

    USE tempdb
    GO
    -- drop table t1;
    CREATE TABLE t1(
    	[月底] DATE,
    	[異動日] DATE,
    	[客戶] VARCHAR(10),
    	[料號] VARCHAR(30),
    	[品名] VARCHAR(30),
    	[規格] VARCHAR(30),
    	[單位名稱] VARCHAR(10),
    	[庫存數量] INT ,
    	[成本] INT, 
    	[pk] INT IDENTITY
    );
    GO
    
    INSERT INTO dbo.t1( 月底, 異動日, 客戶, 料號, 品名, 規格, 單位名稱, 庫存數量, 成本 )
    VALUES  ('2015/02/28', -- 月底 - date
              '2012/07/31', -- 異動日 - date
              'A', -- 客戶 - varchar(10)
              'A003001374', -- 料號 - varchar(30)
              '#7745FL', -- 品名 - varchar(30)
              '1372mm*508M', -- 規格 - varchar(30)
              'a', -- 單位名稱 - varchar(10)
              1, -- 庫存數量 - int
              0  -- 成本 - int
              );
    
    INSERT INTO dbo.t1( 月底, 異動日, 客戶, 料號, 品名, 規格, 單位名稱, 庫存數量, 成本 )
    VALUES  ('2015/02/28', -- 月底 - date
              '2012/2/11', -- 異動日 - date
              'A', -- 客戶 - varchar(10)
              'XFT120723A10', -- 料號 - varchar(30)
              '##7952MP', -- 品名 - varchar(30)
              '610mm*914mm', -- 規格 - varchar(30)
              'a', -- 單位名稱 - varchar(10)
              38, -- 庫存數量 - int
              7953  -- 成本 - int
              );
    INSERT INTO dbo.t1( 月底, 異動日, 客戶, 料號, 品名, 規格, 單位名稱, 庫存數量, 成本 )
     VALUES  ('2015/02/28', -- 月底 - date
              '2015/1/12', -- 異動日 - date
              'L', -- 客戶 - varchar(10)
              'XAT131022A10', -- 料號 - varchar(30)
              '#M 8020P', -- 品名 - varchar(30)
              '610mm*914mm', -- 規格 - varchar(30)
              'a', -- 單位名稱 - varchar(10)
              38, -- 庫存數量 - int
              7953  -- 成本 - int
              );
    INSERT INTO dbo.t1( 月底, 異動日, 客戶, 料號, 品名, 規格, 單位名稱, 庫存數量, 成本 )
     VALUES  ('2015/02/28', -- 月底 - date
              '2015/1/12', -- 異動日 - date
              'K', -- 客戶 - varchar(10)
              'XAT131022A10', -- 料號 - varchar(30)
              '#M 8020P', -- 品名 - varchar(30)
              '610mm*914mm', -- 規格 - varchar(30)
              'a', -- 單位名稱 - varchar(10)
              38, -- 庫存數量 - int
              7953  -- 成本 - int
              );
    INSERT INTO dbo.t1( 月底, 異動日, 客戶, 料號, 品名, 規格, 單位名稱, 庫存數量, 成本 )
     VALUES  ('2015/02/28', -- 月底 - date
              '2015/1/12', -- 異動日 - date
              'j', -- 客戶 - varchar(10)
              'XAT131022A10', -- 料號 - varchar(30)
              '#M 8020P', -- 品名 - varchar(30)
              '610mm*914mm', -- 規格 - varchar(30)
              'a', -- 單位名稱 - varchar(10)
              38, -- 庫存數量 - int
              7953  -- 成本 - int
              );
    
    INSERT INTO dbo.t1( 月底, 異動日, 客戶, 料號, 品名, 規格, 單位名稱, 庫存數量, 成本 )
     VALUES  ('2015/02/28', -- 月底 - date
              '2015/1/12', -- 異動日 - date
              'j', -- 客戶 - varchar(10)
              'XAT131022A10', -- 料號 - varchar(30)
              '#M 8020P', -- 品名 - varchar(30)
              '610mm*914mm', -- 規格 - varchar(30)
              'a', -- 單位名稱 - varchar(10)
              38, -- 庫存數量 - int
              7954  -- 成本 - int
              );
    
    
    SELECT *
    FROM (
    SELECT rn=ROW_NUMBER() OVER(PARTITION BY [規格] , [單位名稱], [庫存數量], [成本] ORDER BY  [規格] )
    , *
     FROM t1) tabA
     WHERE tabA.rn = 1;
      
    --刪除只剩下 rn 為1的資料
    DELETE t1
    WHERE t1.pk IN 
    (
    SELECT tabA.pk
    FROM (
    SELECT rn=ROW_NUMBER() OVER(PARTITION BY [規格] , [單位名稱], [庫存數量], [成本] ORDER BY  [規格] )
    , *
     FROM t1) tabA
     WHERE tabA.rn > 1;
    )
    
    

    如果我有誤解的話,煩請告知,謝謝您!


    亂馬客blog: http://www.dotblogs.com.tw/rainmaker/

    2015年3月8日 上午 02:42