If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

 
Go Back  dBforums > Database Server Software > DB2 > Subquery in Update statement

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old 03-25-10, 15:43
ontheDB ontheDB is offline
Registered User
 
Join Date: Sep 2003
Posts: 80
Subquery in Update statement

I would like to do an update on a table as below. But i get the error : ERROR: ILLEGAL SYMBOL ",". SOME SYMBOLS THAT...


I think i could fix this by putting the subquery into the 'WHERE' clause...but that would mean 4 subqueries: one for each criteria.

Is there a easier way to do this ?


Thanks!


<code>
UPDATE NOTICES C,

(SELECT COUNT (*) AS NUM, A.Notice_ID
,A.Notice_Client

FROM NOTICES A

WHERE 1=1
AND A.Notice_Client IN (15)
AND A.Notice_Expire_Time > CURRENT TIMESTAMP
AND A.Notice_Create_Time > '2009-10-13-00.00.00.000000'

GROUP BY A.RSK_ASMT_TRK_ID, A.RSK_IND_ID
ORDER BY NUM DESC
) AS B

SET C.Notice_Expire_Time = CURRENT TIMESTAMP


WHERE B.NUM > 1
AND C.Notice_Client = B.Notice_Client
AND C.Notice_ID = B.Notice_ID
AND C.Notice_Expire_Time > CURRENT TIMESTAMP
AND C.RSK_Notice_Create_Time IN
(SELECT MAX(D.Notice_Create_Time)
FROM NOTICES D
WHERE D.Notice_Client = C.Notice_Client
AND D.Notice_ID = C.Notice_ID
)

</code>
Reply With Quote
  #2 (permalink)  
Old 03-25-10, 15:58
ARWinner ARWinner is offline
Registered User
 
Join Date: Jan 2003
Posts: 3,575
You cannot update using a join. Try rewriting it using the EXISTS predicate.

Andy
Reply With Quote
  #3 (permalink)  
Old 03-25-10, 16:01
sathyaram_s sathyaram_s is offline
Super Moderator
 
Join Date: Aug 2001
Location: UK
Posts: 4,534
Code:
 
update notices c set  C.Notice_Expire_Time = CURRENT TIMESTAMP
where
(select count(*) FROM NOTICES A WHERE A.Notice_Client IN (15)
AND A.Notice_Expire_Time > CURRENT TIMESTAMP
AND A.Notice_Create_Time > '2009-10-13-00.00.00.000000'
AND C.Notice_Client = A.Notice_Client
AND C.Notice_ID = A.Notice_ID
AND C.Notice_Expire_Time > CURRENT TIMESTAMP
GROUP BY A.RSK_ASMT_TRK_ID, A.RSK_IND_ID ) > 1
and
 C.RSK_Notice_Create_Time IN
(SELECT MAX(D.Notice_Create_Time)
FROM NOTICES D
WHERE D.Notice_Client = C.Notice_Client
AND D.Notice_ID = C.Notice_ID
)
I am not sure if this will satisfy your requirement, but you get the idea of how to write an update stmt in db2 . I suggest you re-write this to improve efficiency, say, using EXISTS (like Andy mentions) and simplifying it ...
__________________
Visit the new-look IDUG Website , register to gain access to the excellent content.
Reply With Quote
  #4 (permalink)  
Old 03-26-10, 09:22
ontheDB ontheDB is offline
Registered User
 
Join Date: Sep 2003
Posts: 80
I wasn't able to get the above posts code to work. But I was able to get the below to work. Thanks for your help.

But I am still curious about using the 'Exists' clause. I had tried that earlier, but failed because I still want only a portion of the subquery (i.e. Num > 1).

So would it be:


WHERE EXISTS (subquery which returns all notices amounts incl NUM=1)
or
WHERE EXISTS (subquery which returns only notices amounts where NUM>1)

If it's the second option, how would one do the subquery in just one level ?


Code:
 
update notices c set  C.Notice_Expire_Time = CURRENT TIMESTAMP
where C.NOTICE_ID IN
(SELECT C.NOTICE_ID FROM
(select count(*), C.NOTICE_ID FROM NOTICES A WHERE A.Notice_Client IN (15)
AND A.Notice_Expire_Time > CURRENT TIMESTAMP
AND A.Notice_Create_Time > '2009-10-13-00.00.00.000000'
AND C.Notice_Client = A.Notice_Client
AND C.Notice_ID = A.Notice_ID
AND C.Notice_Expire_Time > CURRENT TIMESTAMP
GROUP BY A.RSK_ASMT_TRK_ID, A.RSK_IND_ID ) AS B
WHERE B.NUM > 1
)

and
 C.RSK_Notice_Create_Time IN
(SELECT MAX(D.Notice_Create_Time)
FROM NOTICES D
WHERE D.Notice_Client = C.Notice_Client
AND D.Notice_ID = C.Notice_ID
)

Last edited by ontheDB; 03-26-10 at 09:26.
Reply With Quote
  #5 (permalink)  
Old 03-26-10, 10:01
ARWinner ARWinner is offline
Registered User
 
Join Date: Jan 2003
Posts: 3,575
I am not sure if I am getting what you want, but wouldn't it just be:

WHERE EXISTS (subquery which returns only notices amounts where NUM>=1)

instead?

Andy
Reply With Quote
  #6 (permalink)  
Old 03-26-10, 14:39
ontheDB ontheDB is offline
Registered User
 
Join Date: Sep 2003
Posts: 80
Quote:
Originally Posted by ARWinner View Post
I am not sure if I am getting what you want, but wouldn't it just be:

WHERE EXISTS (subquery which returns only notices amounts where NUM>=1)

instead?

Andy
Hi Andy,

Do you mean "Num>=1" or "Num>1" ?

I thought that as well, but was not able to create a query which returns notices num > 1.
I was only able to do so by doing a "2-level" query as in Post #4
Reply With Quote
  #7 (permalink)  
Old 03-26-10, 14:51
ARWinner ARWinner is offline
Registered User
 
Join Date: Jan 2003
Posts: 3,575
Instead of throwing SQL at me that doesn't do what you want, please post the DDL for the relevant tables and then tell me what you are trying to do in a paragraph or two. It is hard to guess your intent from the SQL code.

Andy
Reply With Quote
  #8 (permalink)  
Old 03-26-10, 17:23
tonkuma tonkuma is online now
Registered User
 
Join Date: Feb 2008
Location: Japan
Posts: 2,194
1) I agree Andy's statement.
"It is hard to guess your intent from the SQL code."

It would be better to show sample data and expected result from the sample data.

2) Your subquery may have syntax error.
Quote:
(SELECT COUNT (*) AS NUM, A.Notice_ID
,A.Notice_Client

FROM NOTICES A

WHERE 1=1
AND A.Notice_Client IN (15)
AND A.Notice_Expire_Time > CURRENT TIMESTAMP
AND A.Notice_Create_Time > '2009-10-13-00.00.00.000000'

GROUP BY A.RSK_ASMT_TRK_ID, A.RSK_IND_ID
ORDER BY NUM DESC
) AS B
A.Notice_ID and A.Notice_Client are not in grouping column.
So, aggregate function(for example MAX) is neccesary.

Anyway, here is a query based on my guess at your intent...
Code:
UPDATE NOTICES C
   SET C.Notice_Expire_Time = CURRENT TIMESTAMP 
 WHERE C.Notice_Client IN (15)
   AND C.Notice_Expire_Time > CURRENT TIMESTAMP 
   AND EXISTS
       (SELECT A.RSK_ASMT_TRK_ID
             , A.RSK_IND_ID 
          FROM NOTICES A 
         WHERE A.Notice_Client      = C.Notice_Client
           AND A.Notice_ID          = C.Notice_ID 
           AND A.Notice_Expire_Time > CURRENT TIMESTAMP 
           AND A.Notice_Create_Time > '2009-10-13-00.00.00.000000' 
         GROUP BY
               A.RSK_ASMT_TRK_ID
             , A.RSK_IND_ID 
        HAVING COUNT (*) > 1
       )
   AND C.RSK_Notice_Create_Time
       =
       (SELECT MAX(D.Notice_Create_Time) 
          FROM NOTICES D 
         WHERE D.Notice_Client = C.Notice_Client 
           AND D.Notice_ID     = C.Notice_ID 
       )
;

Last edited by tonkuma; 03-26-10 at 17:32. Reason: Change "SELECT *" in subquery to grouping columns. Add "C.Notice_Client IN (15)".
Reply With Quote
  #9 (permalink)  
Old 03-26-10, 17:48
Lenny77 Lenny77 is offline
Registered User
 
Join Date: Jul 2009
Location: NY
Posts: 886
Thumbs up ...and exists (select 1 from notices a...

Query looks good, but could be undersized:

Code:
UPDATE NOTICES C
   SET C.Notice_Expire_Time = CURRENT TIMESTAMP 
 WHERE C.Notice_Client IN (15)
   AND C.Notice_Expire_Time > CURRENT TIMESTAMP 
   AND EXISTS
       (SELECT 1  FROM NOTICES A 
         WHERE A.Notice_Client       =   C.Notice_Client
           AND A.Notice_ID              =  C.Notice_ID 
           AND A.Notice_Expire_Time  > CURRENT TIMESTAMP 
           AND A.Notice_Create_Time > '2009-10-13-00.00.00.000000' 
         GROUP BY
               A.RSK_ASMT_TRK_ID
             , A.RSK_IND_ID 
        HAVING COUNT (*) > 1
       )
   AND C.RSK_Notice_Create_Time
       =
       (SELECT MAX(D.Notice_Create_Time) 
          FROM NOTICES D 
         WHERE D.Notice_Client = C.Notice_Client 
             AND D.Notice_ID      = C.Notice_ID 
       )
;
Lenny
Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On