2015-06-13 17 views
0

我已經要求我在那裏轉換行值成列,但我嘗試刪除空行和只顯示數據如何刪除兩列空值,只顯示數據

declare @t table (id int,keys varchar(10),val varchar(10)) 
insert into @t (id,keys,val)values (1,'name','hulk'),(2,'age','22'),(3,'name','ironman'),(4,'age','35') 
;with CTE AS (
Select [name],CAST([age] AS INT)age from (
select id,keys,val from @t)t 
PIVOT(MAX(val) for KEYS in ([name],[age]))P 

GROUP BY [name],age) 
Select (C.name),(C.AGE) from CTE C 
LEFT JOIN CTE cc ON c.age = cc.age AND c.name = cc.name 

結果:

name AGE 
NULL 22 
NULL 35 
hulk NULL 
ironman NULL 

所需的結果集:

name AGE 
hulk 22 
ironman 35 
+1

你怎麼知道誰是22,誰是35? – dasblinkenlight

+0

你的桌子總是2個屬性,名稱和年齡?或者我們總是可以假設age屬性緊跟在name屬性之後?你能改變桌子的設計嗎? – Sparky

+0

SELECT name,age FROM

WHERE name IS NOT NULL; – mrunion

回答

0

我認爲,原來按行表的設計是由缺乏有缺陷另一個人的身份。例如,除了名稱,年齡和行標識之外,SSN或任何唯一的人員標識符鍵。

+0

這是一個非常有效的觀點,但不是問題的答案。通常,用戶不能更改表格結構,儘管我希望在這個例子中不是這種情況.... – Sparky

2

你的數據結構相當有缺陷,因爲它沒有人的身份。

如果你認爲「名」開頭的每個記錄,有一些東西,你可以這樣做:

select max(case when keys = 'name' then val end) as name, 
     max(case when keys = 'age' then val end) as age 
from (select t.*, 
      sum(case when keys = 'name' then 1 else 0 end) over (order by id) as numnames 
     from @t t 
    ) t 
group by numnames; 

這非常依賴於id編碼記錄的排序(如您的樣本數據的事實)。如果可能的話,我建議你加入另一個標識符。

編輯:

的SQL Server 2012版本前的等效查詢:

select max(case when keys = 'name' then val end) as name, 
     max(case when keys = 'age' then val end) as age 
from (select t.*, tt.numnames 
     from @t t cross apply 
      (select count(*) as numnames 
      from @t t2 
      where t2.id <= t.id and t2.keys = 'name' 
      ) tt 
    ) t 
group by numnames; 
+0

我如何處理這個上面的查詢情況我知道我們可以在總結和最大案例中處理,但是在透視中我們將如何實現它@gordon – mohan111

+0

我已經嘗試了您的上述查詢,它顯示錯誤的語法消息接近訂單 – mohan111

+0

@ mohan111。 。 。你使用的是什麼版本的SQL Server?自SQL Server 2012以來,累積的總和已被支持。您可以使用'cross apply'做類似的事情。 –

2

我與戈登同意,數據結構是有缺陷的。但是,如果您始終可以假設年齡密鑰ID在名稱密鑰ID後面加1,則以下內容將起作用。但是,如果你可以改變表結構,那就更好了..

declare @t table (id int,keys varchar(10),val varchar(10)) 
insert into @t (id,keys,val) 
values (1,'name','hulk'),(2,'age','22'),(3,'name','ironman'),(4,'age','35') 


select nc.id,nc.val as Name,xx.age 
from @t nc 
join (select id,val as Age from @t where keys='age') xx on xx.id=nc.id+1 
where keys='name' 

但是,代碼可能依賴於有關密鑰的一個壞的假設......

+0

謝謝@sparky我得到了結果集,但你可以建議我在上面的樞軸查詢 – mohan111

0

如果我猜測正確,你想關於名字和年齡的透視圖,以及數據的不尋常格式。你可以做的是將數據關聯起來,如name:hulkage:22等等。所以你可以做的是:

declare @t table (id int,keys varchar(10),val varchar(10)) 
insert into @t (id,keys,val)values (1,'name','hulk'),(1,'age','22'), 
(2,'name','ironman'),(2,'age','35'); 
with CTE AS (
Select [name],CAST([age] AS INT)age from (
select id,keys,val from @t)t 
PIVOT(MAX(val) for KEYS in ([name],[age]))P 
GROUP BY [name],age) 
Select (C.name),(C.AGE) from CTE C 
LEFT JOIN CTE cc ON c.age = cc.age AND c.name = cc.name 

一旦關係創建,你會得到所需的輸出。我通過輸入Id爲name:hulkage:22來創建關係,輸入的數據是Id:1中輸入的數據,也可以是您在應用程序中使用此數據定義的任何對象。

+0

Id爲什麼你已經改變Id列到你的要求? – mohan111

+0

「Id」列的值指定數據用於相同的「Id」。這意味着當你分別輸入'name'和'age'到兩個不同的行時,你需要兩個數據之間的關係。主要是在這裏你說的是,兩個不同的條目是同一個人'綠巨人'或'鐵人'。這個關係需要用一些公共密鑰來指定。因此,'Id'。 – debatanu