Solved

How to create an update query with a group by clause

Posted on 2011-09-06
7
261 Views
Last Modified: 2012-05-12
I have the following query that provides the result set that I want to update...

select customer.customer_id, MAX(order_date) as last_order, credit_status
from oe_hdr inner join customer on customer.company_id = oe_hdr.company_id
AND customer.customer_id = oe_hdr.customer_id
WHERE     oe_hdr.company_id = '01'
AND (oe_hdr.delete_flag = 'N') AND (oe_hdr.projected_order = 'N') AND (oe_hdr.cancel_flag = 'N')
and credit_status not in ('REJECT', 'BAD DEBT')
and customer.delete_flag = 'N'
and customer.company_id = '01'
group by customer.customer_id, credit_status
HAVING MAX(order_date) < DATEADD(yy,-3,getdate())


However, I cannot get the correct syntax for the update query in order to be able to update the credit_status field.

I was trying to do something simple like...

update customer
set credit_status = 'REJECT'

from oe_hdr inner join customer on customer.company_id = oe_hdr.company_id
AND customer.customer_id = oe_hdr.customer_id
WHERE     oe_hdr.company_id = '01'
AND (oe_hdr.delete_flag = 'N') AND (oe_hdr.projected_order = 'N') AND (oe_hdr.cancel_flag = 'N')
and credit_status not in ('REJECT', 'BAD DEBT')
and customer.delete_flag = 'N'
and customer.company_id = '01'
group by customer.customer_id, credit_status
HAVING MAX(order_date) < DATEADD(yy,-3,getdate())

But it doesn't like that I have a 'group by' in there.  Can anybody help me get the correct syntax?

Thanks
0
Comment
Question by:timoteoga
7 Comments
 
LVL 9

Expert Comment

by:jerrypd
ID: 36488819
well you obviously cant update a group by...
but from what i see you dont need it for the update query?
if you were to try running it without the group by - does it update the record(s) of interest?
if not, you could just do a rollback and it will "undo" the update.
0
 

Author Comment

by:timoteoga
ID: 36488850
If you go without the group by, it then says that it's incorrect syntax near 'HAVING'
0
 
LVL 9

Expert Comment

by:mimran18
ID: 36488893
Hi
 A sample is here.
 
Drop table test
Go
Create table test
(ID int,
[SName] nvarchar(50),
[Marks] int)
Go

Drop table testMarks
Go
Create table testMarks
(ID int,
[Subject] nvarchar(50),
[Marks] int)
Go

Insert  into test values (1,'John',0)
Insert  into test values (2,'Robert',0)
Insert  into test values (3,'William',0)
GO

Insert  into testMarks values (1,'Math',40)
Insert  into testMarks values (1,'English',90)
Insert  into testMarks values (1,'Computer',80)

GO

Insert  into testMarks values (2,'Math',80)
Insert  into testMarks values (2,'English',80)
Insert  into testMarks values (2,'Computer',90)

GO

Update test set [Marks]=(Select SUM([Marks]) from [testMarks]
Where test.[ID]=[testMarks].[ID] Group By [ID] )

GO

Select * from test

Open in new window

0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 10

Accepted Solution

by:
dwe761 earned 500 total points
ID: 36488899
You may be able to use something like this but the join fields in the last 3 lines may have to be adjusted because I didn't know which table some of the fields came from:



update customer
set credit_status = 'REJECT'

from customer
INNER JOIN 
(
select customer.customer_id, MAX(order_date) as last_order, credit_status
from oe_hdr inner join customer on customer.company_id = oe_hdr.company_id
AND customer.customer_id = oe_hdr.customer_id
WHERE     oe_hdr.company_id = '01'
AND (oe_hdr.delete_flag = 'N') AND (oe_hdr.projected_order = 'N') AND (oe_hdr.cancel_flag = 'N')
and credit_status not in ('REJECT', 'BAD DEBT')
and customer.delete_flag = 'N'
and customer.company_id = '01'
group by customer.customer_id, credit_status
HAVING MAX(order_date) < DATEADD(yy,-3,getdate())
) c
ON customer.customer_id = c.customer_id AND
	customer.order_date = c.last_order AND
	customer.credit_state = c.credit_status

Open in new window

0
 

Author Closing Comment

by:timoteoga
ID: 36488940
Perfect - thanks!
0
 
LVL 59

Expert Comment

by:Kevin Cross
ID: 36488964
Yes, you can do it that way, but I would look at what you intend and rewrite. It appears you are simply using the GROUP BY for the HAVING clause to filter out where a given customer doesn't have any orders meeting a specific criteria after three years ago.

You can eliminate the JOIN completely since you are NOT actually using the results of the derived table in your UPDATE. And do not need to GROUP BY since MAX(order_date) < {some date} is the same as NOT EXISTS {order_date >= {some date}}.
update customer
set credit_status = 'REJECT'
where not exits (
   select 1
   from oe_hdr 
   where customer.company_id = oe_hdr.company_id
   and customer.customer_id = oe_hdr.customer_id
   and (oe_hdr.delete_flag = 'N') AND (oe_hdr.projected_order = 'N') AND (oe_hdr.cancel_flag = 'N')
   and oe_hdr.order_date >= DATEADD(yy,-3,getdate())
)
and customer.credit_status not in ('REJECT', 'BAD DEBT')
and customer.delete_flag = 'N'
and customer.company_id = '01'
;

Open in new window

0
 
LVL 59

Expert Comment

by:Kevin Cross
ID: 36488991
BTW, I was just posting since I had been typing this up to show you an example of what I meant before seeing you had accepted. I figured I would post it anyway for your and future readers' benefit. I am in no way discounting what you already have. If you truly need to do a GROUP BY with an update, using a derived table and UPDATE with JOIN is a very viable option.

Anyway, best regards and happy coding,

Kevin
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

If you have heard of RFC822 date formats, they can be quite a challenge in SQL Server. RFC822 is an Internet standard format for email message headers, including all dates within those headers. The RFC822 protocols are available in detail at:   ht…
This article explains how to reset the password of the sa account on a Microsoft SQL Server.  The steps in this article work in SQL 2005, 2008, 2008 R2, 2012, 2014 and 2016.
Using examples as well as descriptions, and references to Books Online, show the documentation available for datatypes, explain the available data types and show how data can be passed into and out of variables.
Viewers will learn how the fundamental information of how to create a table.

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now