2017-01-09 49 views
-2

我的表有以下strucuture如何去sql中的同一行中的不同值的列?

 
empno empname loan ref amount 
1  abc  123  100 
1  abc  456  200. 

即僱員可以利用兩筆貸款(比如汽車和摩托車)。

輸出預期:

 
empno empname  loan ref1 amt loanref2 amt 
1  abc   120  100 456   200 

以避免重複EMPNO重複。如何去在SQL中呢?

+3

有多少重複的行可以爲每個EMPNO?如果這是可變的,你需要一個可變列數的查詢,這是不可能的。另外,你有嘗試過什麼嗎?請張貼您的嘗試和您遇到的問題。 – Aleksej

+3

開始:這是一個可怕的桌子設計。如果在名爲'abc'的另一個記錄中找到empno 1,而在名稱爲'efg'的另一個記錄中找到另一個記錄呢?那麼,你可以爲一名員工提供多少條目?你想獲得多少列? –

+0

另外,你爲什麼要避免表中的「重複」?重複項有什麼問題?在這種情況下,它們是完全有效的,正常的和標準的。你有沒有需要解決的真正問題? – mathguy

回答

1

關於以前關於表格設計的評論 - 事實上,表格中有冗餘;你可以將empname存儲在另一個表中,你可以在這裏與你的表連接以避免這種情況;每一次冗餘都是潛在的矛盾。但是,如果我們有一個爲查詢和最小化必要連接而優化的表設計,它可能會從其他地方的批處理作業中填充,然後設計就會合適。

你想在這裏做什麼通常被稱爲'橫向旋轉'。 我們在這裏缺少一些信息,所以我假設貸款的最大數量爲2.我們需要一種機制,允許我們將數據放入col1或col2,具體取決於它是同一個empno的第一行還是第二行。這就是我們生成序列號的原因。最後,我們使用SUM(CASE seq WHEN ...)表達式與GROUP BY結合使用來減少行數並平整表格。

這裏所說:

-- first global table expression - the input table 
-- The table could exist already, and then this would not be needed. 
WITH foo(empno,empname,loanref,amount) AS (
      SELECT 1,'abc',123,100 
UNION ALL SELECT 1,'abc',456,200 
) 
-- second global table expression - add sequence number 
-- this needs to be in the query 
, foo_numbered AS (
SELECT 
    -- need a number: 1 for the first, 2 for the second loan 
    ROW_NUMBER() OVER(PARTITION BY empname ORDER BY loanref) AS seq 
, * 
FROM foo 
) 
SELECT 
    empno 
, empname 
, MAX(CASE seq WHEN 1 THEN loanref END) AS loanref_1 
, SUM(CASE seq WHEN 1 THEN amount END) AS amount_1 
, MAX(CASE seq WHEN 2 THEN loanref END) AS loanref_2 
, SUM(CASE seq WHEN 2 THEN amount END) AS amount_2 
FROM foo_numbered 
GROUP BY 
    empno 
, empname 
; 

玩的開心

馬爾科

相關問題