[英]SQL: changing table (ID, [Datetime], [INT]) to (ID, Start_DT, End_DT, [INT])
I have some old data in this format: 我有这种格式的旧数据:
ID DT NUM
1 6-1-2012 2
1 6-2-2012 2
1 6-3-2012 4
1 6-4-2012 4
1 6-5-2012 8
1 6-6-2012 8
1 6-7-2012 8
1 6-8-2012 16
1 6-9-2012 2
1 6-10-2012 2
And I need it to look like this: 我需要它看起来像这样:
ID START_DT END_DT NUM
1 6-1-2012 6-2-2012 2
1 6-3-2012 6-4-2012 4
1 6-5-2012 6-7-2012 8
1 6-8-2012 6-8-2012 16
1 6-9-2012 6-10-2012 2
This is the best example of the data that I could quickly come up with. 这是我可以快速提出的数据的最佳示例。 I would love to clarify if I accidently included some misunderstanding(s) in it.
如果我意外地包含一些误解,我想澄清一下。
The Rules: 规则:
EDIT: this is very awkward..... (there MUST be a better answer)... i haven't tested this yet with a lot of conditions but it looks okay from the start.... and had to manually find and replace all the field names (be kind) 编辑:这是非常尴尬..... (必须有一个更好的答案)... 我还没有测试这个有很多条件但它从一开始看起来没问题....并且不得不手动查找并替换所有字段名称(善意)
select * from (
select *,row_number() over (partition by if_id, [z.num] order by if_id, [y.num]) as rownum
from (
select y.id,
y.dt as [y.dt],
z.dt as [z.dt],
y.num
from #temp as y
outer apply (select top 1 id, dt, num
from #temp as x
where x.id = y.id and
x.dt > y.dtand
x.num <> y.num
order by x.dt asc) as z ) as x ) as k
where rownum=1
order by [y.dt]
select id,min(dt) as start_date, max(dt) as end_date, num
from whatevertablename_helps_if_you_supply_these_when_asking_for_code
group by 1,4
It's also possible to do it as a subquery to get the min and a subquery to get the max, but don't think you need to do that here. 它也可以作为子查询来获取最小值和子查询以获得最大值,但不要认为你需要在这里做到这一点。
My answer is Postgres...I think you'll need to change the group by statement to be id,num instead in t-sql. 我的回答是Postgres ...我认为你需要将group by语句更改为id,num而不是t-sql。
Adding: 添加:
How do you know that it is 你怎么知道它是
1 6-1-2012 6-2-2012 2 1 6-1-2012 6-2-2012 2
1 6-9-2012 6-10-2012 2 1 6-9-2012 6-10-2012 2
and not 并不是
1 6-1-2012 6-10-2012 2 1 6-1-2012 6-10-2012 2
1 6-2-2012 6-9-2012 2 1 6-2-2012 6-9-2012 2
You need more business rules to determine that 您需要更多业务规则来确定
select id, [y.dt] as start_dt, [z.dt] as end_dt, num from (
select *,row_number() over (partition by id, [z.dt] order by id, [y.dt]) as rownum
from (
select y.id,
y.dt as [y.dt],
z.dt as [z.dt],
y.num
from #temp as y
outer apply (select top 1 id, dt, num
from #temp as x
where x.id = y.id and
x.dt > y.dt and
x.num <> y.num
order by x.dt asc) as z ) as x ) as k
where rownum=1
order by id, [y.dt]
and that gives us... (with different data) 这给了我们......(有不同的数据)
id start_dt end_dt num
6 2011-10-01 00:00:00.000 2012-01-18 00:00:00.000 896
6 2012-01-18 00:00:00.000 2012-02-01 00:00:00.000 864
6 2012-02-01 00:00:00.000 NULL 896
i posted that up at the top about an hour ago maybe...? 大约一个小时前我在顶部发布了这个...也许......? and said it was awkward (and sloppy)... i was wondering if anyone has a better answer because mine sucks.
并说这很尴尬(而且草率)......我想知道是否有人有更好的答案,因为我很糟糕。 but i don't understand why people keep posting that they need better business rules and need to know how to handle certain situations.
但我不明白为什么人们不断发布他们需要更好的业务规则并且需要知道如何处理某些情况。 this code does exactly what i want except end_dt is the datetime of the new num and not the last occurance of the current num.... but I can work with that.
这段代码正是我想要的,除了end_dt是新num的日期时间而不是当前num的最后一次出现....但我可以使用它。 It is better than nothing.
总比没有好。 (sorry, frustrated).
(抱歉,沮丧)。
Business rule: the data is already there. 业务规则:数据已存在。 it should show the logical span.
它应该显示逻辑跨度。 I need the start_dt and end_dt for num... When NUM = Y, the Start date is when NUM changes from X to Y and the End Date is when Y changes to Z. I can't give you more than I have myself with all of this... These rules were enough for me...??
我需要num_的start_dt和end_dt ...... 当NUM = Y时,开始日期是NUM从X变为Y而结束日期是Y变为Z.我不能给你超过我自己所有这些......这些规则对我来说已经足够了......?
ok, same data: 好的,相同的数据:
id start_dt end_dt num
1 6-1-2012 6-3-2012 2
1 6-3-2012 6-5-2012 4
1 6-5-2012 6-8-2012 8
1 6-8-2012 6-9-2012 16
1 6-9-2012 NULL 2
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.