[英]merging records for sql table based on column data
我在t_resourcetable中有一些骯臟的資源使用記錄,看起來像這樣
resNo subres startdate enddate 1 2 2012-01-02 22:03:00.000 2012-01-03 00:00:00.000 1 2 2012-01-03 00:00:00.000 2012-01-04 00:00:00.000 1 2 2012-01-04 00:00:00.000 2012-01-04 16:23:00.000 1 3 2012-01-06 16:23:00.000 2012-01-06 22:23:00.000 2 2 2012-01-04 05:23:00.000 2012-01-06 16:23:00.000
我需要這些臟行以這種方式合並
resNo subres startdate enddate 1 2 2012-01-02 22:03:00.000 2012-01-04 16:23:00.000 1 3 2012-01-06 16:23:00.000 2012-01-06 22:23:00.000 2 2 2012-01-04 05:23:00.000 2012-01-06 16:23:00.000
這應該更新到同一張表,我有超過40k的行,所以不能使用游標,請幫助我通過一些優化的sql語句清理此類數據。
temptable和group提供的解決方案不會遇到類似的情況。 我正在尋找沒有基於游標的解決方案
resNo subres startdate enddate 1 2 2012-01-02 22:03:00.000 2012-01-03 00:00:00.000 1 2 2012-01-03 00:00:00.000 2012-01-04 00:00:00.000 1 2 2012-01-04 00:00:00.000 2012-01-04 16:23:00.000 1 2 2012-01-14 10:09:00.000 2012-01-15 00:00:00.000 1 2 2012-01-15 00:00:00.000 2012-01-16 00:00:00.000 1 2 2012-01-16 00:00:00.000 2012-01-16 03:00:00.000 1 3 2012-01-06 16:23:00.000 2012-01-06 22:23:00.000 2 2 2012-01-04 05:23:00.000 2012-01-06 16:23:00.000
我需要這些臟行以這種方式合並
resNo subres startdate enddate 1 2 2012-01-02 22:03:00.000 2012-01-04 16:23:00.000 1 2 2012-01-14 10:09:00.000 2012-01-16 03:00:00.000 1 3 2012-01-06 16:23:00.000 2012-01-06 22:23:00.000 2 2 2012-01-04 05:23:00.000 2012-01-06 16:23:00.000
plesae讓我擺脫了這個骯臟的數據問題
您需要按resNo和subRes對數據進行分組,如下所示:
select resNo, subRes, min(startdate), max(enddate)
from t_resourcetable
group by resNo, subRes
並將結果插入臨時表中。
然后,您可以截斷t_resourcetable並將臨時模板的結果插入其中
第一步是創建備份:
select *
into t_resourcetable_backup20120327
from t_resourcetable
然后更新由resNo和subRes分組的第一條記錄的結束日期:
update t_resourcetable
set enddate = (select max (enddate)
from t_resourcetable t1
where t1.resNo = t_resourcetable.resNo
and t1.subRes = t_resourcetable.subRes)
where not exists (select null
from t_resourcetable t1
where t1.resNo = t_resourcetable.resNo
and t1.subRes = t_resourcetable.subRes
and t1.startdate < t_resourcetable.startdate)
最后刪除額外的記錄:
delete t_resourcetable
where exists (select null
from t_resourcetable t1
where t1.resNo = t_resourcetable.resNo
and t1.subRes = t_resourcetable.subRes
and t1.startdate < t_resourcetable.startdate)
如果resNo和subRes的唯一組合的開始日期重復,則將保留重復項。 您還應該檢查結束日期是否總是具有相應的開始日期,因為您會失去空白-但這可能只是您想要的。
除了創建備份外,您還可以將更新/刪除包裝在事務中,在刪除和回滾后進行選擇,然后在Excel中檢查數據,如果一切正常,請重復事務但這次進行提交。
更新:此查詢標識差距。 如果您使用的是Sql Server 2000,請將CTE轉換為派生表。 首先返回沒有前任資源的列表,最后返回后繼資源。 兩者都算差距。 然后,列表由resNo,subRes和空位號連接。
;with first as (
select resNo, subres, startdate,
row_number() over (partition by resNo, subres order by startdate) rowNumber
from t_resourcetable
where not exists (select null
from t_resourcetable t1
where t1.resNo = t_resourcetable.resNo
and t1.subres = t_resourcetable.subres
and t1.enddate = t_resourcetable.startdate)
),
last as (
select resNo, subres, enddate,
row_number () over (partition by resNo, subres order by enddate) rowNumber
from t_resourcetable
where not exists (select null
from t_resourcetable t1
where t1.resNo = t_resourcetable.resNo
and t1.subres = t_resourcetable.subres
and t1.startdate = t_resourcetable.enddate)
)
select first.resno, first.subres, first.startdate, last.enddate
from first
inner join last
on first.resNo = last.resNo
and first.subres = last.subres
and first.rowNumber = last.rowNumber
你可以試試這個嗎?
SELECT resno,
subres,
startdate,
MIN(enddate) AS enddate
FROM (SELECT t1.resno,
t1.subres,
t1.startdate,
t2.enddate
FROM t_resourcetable t1,
t_resourcetable t2
WHERE t1.enddate <= t2.enddate
AND NOT EXISTS (SELECT *
FROM t_resourcetable t3
WHERE ( t1.resno = t3.resno
AND t1.subres = t3.subres
AND t1.startdate > t3.startdate
AND t1.startdate <= t3.enddate )
OR ( t2.resno = t3.resno
AND t2.subres = t3.subres
AND t2.enddate >= t3.startdate
AND t2.enddate < t3.enddate )))t
GROUP BY resno,
subres,
startdate
圖像就像
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.