Update query combined by group and set minimum dat

2019-08-08 02:15发布

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...

标签: sql db2
1条回答
贼婆χ
2楼-- · 2019-08-08 02:47

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
查看更多
登录 后发表回答