问题
I'm totally confused about how to get this query done.
How to achieve this query with no big performance impact (if table contains thousands rows) ?
Please advice!
MyTable
pktimestmp | sw_id | url_id | open_date | end_date
-------------------------------------------------------
xxx0 | 101 | com | 2013-01-01 | 2013-01-30
xxx1 | 202 | net | 2013-01-01 | 2013-01-30
xxx2 | 202 | net | 2013-01-15 | 2013-02-28 *
xxx3 | 303 | com | 2013-01-01 | 2013-01-30
xxx4 | 303 | com | 2013-02-01 | 2013-02-15 *
xxx5 | 303 | com | 2013-03-01 | 2013-03-15 *
xxx6 | 404 | org | 2013-01-01 | 2013-01-30
xxx7 | 404 | org | 2013-02-01 | 2013-02-15 *
xxx8 | 404 | gov | 2013-02-01 | 2013-02-15
xxx9 | 404 | gov | 2013-02-01 | 2013-02-15
...
update query on:
dates where software and url are the same (i.e. sw_id and url_id).
We set opendate and enddate to less (min) occurrence.
xxx2 | 202 | net | 2013-01-15 | 2013-02-28
will be
xxx2 | 202 | net | 2013-01-01 | 2013-01-30
here we have updated
open_date to min(open_date)
and
end_date to min(end_date)
from same sw and url.
(it would be nice if we only update where there is a difference, for example no need to update xxx8 and xxx9 as they are "same")
MyTable ( * = updated rows )
pktimestmp | sw_id | url_id | open_date | end_date
-------------------------------------------------------
xxx0 | 101 | com | 2013-01-01 | 2013-01-30
xxx1 | 202 | net | 2013-01-01 | 2013-01-30
xxx2 | 202 | net | 2013-01-01 | 2013-01-30 *
xxx3 | 303 | com | 2013-01-01 | 2013-01-30
xxx4 | 303 | com | 2013-01-01 | 2013-01-30 *
xxx5 | 303 | com | 2013-01-01 | 2013-01-30 *
xxx6 | 404 | org | 2013-01-01 | 2013-01-30
xxx7 | 404 | org | 2013-01-01 | 2013-01-30 *
xxx8 | 404 | gov | 2013-02-01 | 2013-02-15
xxx9 | 404 | gov | 2013-02-01 | 2013-02-15
Thanks in advance! (And no I have no rights to re-model the table) :)
Any help is appreciated, urls, hints, ebooks, sites...
回答1:
The following should work (on pretty much any RDBMS):
UPDATE MyTable as a SET (open_date, close_date)
= (SELECT MIN(open_date), MIN(close_date)
FROM MyTable as b
WHERE b.sw_id = a.sw_id
AND b.url_id = a.url_id)
WHERE EXISTS (SELECT *
FROM MyTable as b
WHERE b.sw_id = a.sw_id
AND b.url_id = a.url_id
AND (b.open_date < a.open_date OR b.close_date < a.close_date))
Which generates the expected, with only 4 rows updated (tested against my iSeries instance):
PKTIMESTAMP SW_ID URL_ID OPEN_DATE CLOSE_DATE
xxx0 101 com 2013-01-01 2013-01-30
xxx1 202 net 2013-01-01 2013-01-30
xxx2 202 net 2013-01-01 2013-01-30
xxx3 303 com 2013-01-01 2013-01-30
xxx4 303 com 2013-01-01 2013-01-30
xxx5 303 com 2013-01-01 2013-01-30
xxx6 404 org 2013-01-01 2013-01-30
xxx7 404 org 2013-01-01 2013-01-30
xxx8 404 gov 2013-02-01 2013-02-15
xxx9 404 gov 2013-02-01 2013-02-15
来源:https://stackoverflow.com/questions/14485480/update-query-combined-by-group-and-set-minimum-dates