2011-07-11 62 views
0

我對此問題有一個後續問題。SQL服務器根據字段中的值每天選擇一條記錄

SQL Server Get values of top three records and display in one row per person

ID Name  Date1     Value2 Date2     Value2 Date3     Value3 Date4     Value4 Date5     Value5 Date6     Value6 Date7     Value7 

12 John Smith 2011-06-27 14:06:10.517 None 2011-06-27 00:17:53.987 None 2011-06-26 21:56:07.577 Medium 2011-06-26 13:32:31.190 None 2011-06-26 02:47:54.357 None 2011-06-25 19:32:00.000 Medium 2011-06-25 13:43:22.000 Medium 
12 Jack Smith 2011-06-27 05:54:59.320 None 2011-06-26 06:28:55.033 None 2011-06-25 16:25:00.000 Medium 2011-06-25 14:27:11.017 Large 2011-06-25 06:11:45.793 Large 2011-06-24 19:33:24.520 Medium 2011-06-24 06:17:35.887 None 

我需要每天一個值。如果有一個不等於'無'的值,我需要該記錄給定的日期。

這裏的結果應該是什麼樣子:

ID Name  Date1     Value2 Date2     Value2 Date3     Value3 Date4     Value4 Date5     Value5 Date6     Value6 Date7     Value7 

12 John Smith 2011-06-27 00:17:53.987 None 2011-06-26 21:56:07.577 Medium 2011-06-25 13:43:22.000 Medium 
12 Jack Smith 2011-06-27 05:54:59.320 None 2011-06-26 06:28:55.033 None 2011-06-25 06:11:45.793 Large 2011-06-24 19:33:24.520 Medium 

我的原始數據的格式如下: (記錄我需要標有*)

ID Name  Date     Value 
12 JACK Smith 2011-06-27 05:54:59.320 None * 
12 JACK Smith 2011-06-26 06:28:55.033 None * 
12 JACK Smith 2011-06-25 16:25:00.000 Medium 
12 JACK Smith 2011-06-25 14:27:11.017 Large 
12 JACK Smith 2011-06-25 06:11:45.793 Large * 
12 JACK Smith 2011-06-24 19:33:24.520 Medium * 
12 JACK Smith 2011-06-24 06:17:35.887 None 
12 JACK Smith 2011-06-23 00:30:28.363 None * 
12 JACK Smith 2011-06-22 00:47:41.800 None * 
12 JACK Smith 2011-06-21 06:03:55.000 None * 

任何幫助是極大的讚賞。

+0

試圖理解你的問題......你可以(手動)將樣本記錄集放到一起,看看結果應該是什麼樣子,根據你迄今爲止提供的內容。 – Chains

+0

這甚至可能嗎? – Claudia

+0

是的 - 請參閱下面的我的(新)答案。這是一個非常簡單的解決方案,但有很多代碼來操縱日期。我添加了很多評論,以防它有幫助。 – Chains

回答

0

你問什麼不清楚......

可以限制使用WHERE子句您的記錄(這將完全刪除的記錄)......可能更容易做到這一點你的原始記錄(在鏈接你貼)比上述修訂後的記錄...

WHERE value <> 'None' 

或者你可以保持的記錄,只是限制了功能的顯示(許多選項 - 這裏有一個:)

Replace('None','') 

...這裏的另一個問題:

CASE value WHEN 'None' THEN '' ELSE value END 
0

像這樣的事情,然後...這將工作,但它可能有一個錯字,因爲我只是打字出來未經測試。

SELECT 
    ID, 
    Name, 
    Right(
    -- The Right() function will strip-off the leading integer that you need to first add to the date so 
    -- you can get the record you want. 
     Min(
     -- The Min() function will get a single record for you 
     -- the functions below will manipulate the date so that records with a non-'None' value are 
     -- guaranteed to have a larger date then records with a 'None' value. This is done by adding 
     -- an integer to the front of the date -- '0' for non-'None' values, and '1' for 'None' values. 
      Cast(CASE value WHEN 'None' THEN 1 ELSE 0 END as varchar(1)) 
      -- The CASE statement outputs a 0 or 1 
      -- The Cast() function changes the output to text instead of a number, so you can use the 
      -- string concat (+) later. 
      + 
      -- string concatenation, which only works on text, not numbers 
      Cast(Date as varchar(25)) 
      -- The Cast() function changes the date to text, so you can use it with the string concat above 
      ) 
     , 23 
     -- 23 should be the number of characters in the date itself 
     -- adjust the number up or down as necessary.    
     ) as myDate, 
    Value 
FROM 
    Table 
GROUP BY 
    ID, 
    Name, 
    Value 

這應該會減少您的原始記錄集,以便它只包含您想要的記錄。之後,您可以應用@Manfred Sorg爲您的第一個問題提出的水平解決方案。

0

你想換位,我想。

你應該使用數據透視表的一些怎麼說

表:支點 值:0,1,2,...

的想法能夠將每個價值定位每一天在正確的列和之後,你需要做的查詢組得到一個單列

select 

resultset.id, resultset.Name, 

case when not max(date1) is null then max(date1) 
else null end as date1, 
case when not max(value1) is null then max(value1) 
else '' end as value1, 
... 
... 
... 

from (

    select mltwngd.id, mltwngd.Name, 
     //sorry that part is ugly, ugly, 
     case when i=0 then datedd(day, mltwngdg.periodstart, auxtable.i) 
     else '' end as date1, 

     case when i=0 then datedd(day, mltwngdg.periodstart, auxtable.i) 
     else '' end as value1, 

     ... 
     ... 
     ... 

    from mylinealtable_with_nogooddesing mltwngd 

    inner join 
    (
     select id, min(date) periodstart, 
     max(date) as periodend, 
     datediff("dd", max(date), min(date)) as days 
     from mylinealtable_with_nogooddesing 
     where ... 
     group by id 
    ) as mltwngdg 
    on mltwngdg.id = mltwngd.id 

    inner join  
    (
     select * 
     from pivot 
     where i >= 0 and i < @period_max_days 
    )auxtable 
    on auxtable.i >0 and auxtable.i < days 
)resultset 

group by resultset.id, resultset.Name 

簡化的想法是

declare @aux table (id int, [name] varchar(20), 
         date1 datetime, 
         valor1 varchar(10), 
         date2 datetime, 
         valor2 varchar(10) 
        ) 


insert into @aux(id, [name], date1, valor1, date2, valor2) 
values(1,'CARLOS','20110201','XP',NULL, '') 

insert into @aux(id, [name], date1, valor1, date2, valor2) 
values(1,'CARLOS',NULL, '','20110201','WIN7') 

select * from @aux 

select 
    x.id, x.name, 
    case when not max(date1) is null then max(date1) 
    else null end as date1, 
    case when not max(valor1) is null then max(valor1) 
    else null end as valor1, 
    case when not max(date2) is null then max(date2) 
    else null end as date2, 
    case when not max(valor1) is null then max(valor2) 
    else null end as valor2 
from @aux x 
group by x.id, x.name 
相關問題