Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
Hommer
Aged Yak Warrior
808 Posts |
Posted - 2006-07-18 : 15:36:23
|
| Hi, All!I need your help to get this max function to work in the where clause. Basically I am after a mailing list for certain customers. The account table has a AcctName column, but for some of them, they are null. For these accounts, I need to bring in the OrderContact from Orders table, but need to get the name for the latest order. Here are the tables and data.CREATE TABLE [dbo].[Accts] ( [Acct] [int] NULL , [AcctName] [nvarchar] (50) NULL , [AcctContact] [nvarchar] (50) NULL , [Address] [nvarchar] (50) NULL ) ON [PRIMARY]CREATE TABLE [dbo].[Orders] ( [OrderID] [int] NULL , [Acct] [int] NULL , [OrderDate] [smalldatetime] NULL , [OrderContact] [nvarchar] (50) NULL ) ON [PRIMARY]insert into accts values(1,'ABC', 'Jeff', '123 Main')insert into accts values(2,'Zipz',NULL,'3221 Wall')insert into Orders values(1,1, '2005-01-01 ','Whos who')insert into Orders values(2,2, '2005-01-01 ', 'Well')insert into Orders values(3,2,'2006-02-01 ','Got it')And here's what I got.select AcctName, Address, AcctContact, OrderContactfrom Accts join Orders on Accts.Acct=Orders.Acctwhere OrderDate = (select max(OrderDate) from Orders group by Acct)TIA |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2006-07-18 : 15:39:56
|
| What is the expected result set given this sample data?Tara Kizer |
 |
|
|
Hommer
Aged Yak Warrior
808 Posts |
Posted - 2006-07-18 : 15:54:14
|
| Here they are:1 ABC Jeff 123 Main2 Zipz Got it 3221 WallIt is the "Got it" part. It has to come from Orders and it has to be based on the max OrderDate, i.e. it should be "Got it", but not "Well".Thanks! |
 |
|
|
humanpuck
Yak Posting Veteran
94 Posts |
Posted - 2006-07-18 : 15:57:49
|
| Try putting it in a having clause.select AcctName, Address, AcctContact, OrderContactfrom Accts join Orders on Accts.Acct=Orders.Acctgroup by AcctName, Address, AcctContact, OrderContacthaving OrderDate = max(OrderDate)union allselect '','','',ordercontactfrom orders awhere not exists ( select OrderContactfrom Accts join Orders b on Accts.Acct=Orders.Acctwhere a.ordercontact = b.ordercontactgroup by OrderContacthaving OrderDate = max(OrderDate))group by ordercontacthaving orderdate = max(orderdate) |
 |
|
|
SreenivasBora
Posting Yak Master
164 Posts |
Posted - 2006-07-18 : 16:02:26
|
| select A.Acct,A.AcctName, A.Address, A.AcctContact, O.OrderContact,O.OrderDatefrom (Accts A join Orders O on A.Acct=O.Acct )Where O.OrderDate In (Select max(C.OrderDate) from Orders C Where A.Acct = C.Acct group by C.Acct)1 ABC 123 Main Jeff Whos who 2005-01-01 00:00:002 Zipz 3221 Wall NULL Got it 2006-02-01 00:00:00Choose which clumns U want.With RegardsBSR |
 |
|
|
Hommer
Aged Yak Warrior
808 Posts |
Posted - 2006-07-18 : 16:02:49
|
| Yah, that is where I am having trouble with, because the message saysAn aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list, and the column being aggregated is an outer reference. I have rearranged the query many different ways, but have not figured it out. |
 |
|
|
humanpuck
Yak Posting Veteran
94 Posts |
Posted - 2006-07-18 : 16:07:47
|
| I didn't notice you already had Orders in your query you don't even need a subquery. |
 |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2006-07-18 : 16:07:47
|
Here is my solution. I'm sure someone else will be able to figure this out without a union. The first query in the union is for the ones that do not have nulls. The second is for the ones with nulls. select a.Acct, a.AcctName, a.AcctContact, a.Addressfrom accts ainner join orders oon a.acct = o.acctwhere a.acctcontact is not nullunion allselect a.Acct, a.AcctName, o.OrderContact, a.Addressfrom accts ainner join orders oon a.acct = o.acctinner join( select o2.acct, max(o2.orderdate) as orderdate from orders o2 inner join accts a2 on a2.Acct = o2.Acct where a2.acctcontact is null group by o2.acct) ton o.acct = t.acct and o.orderdate = t.orderdate Tara Kizer |
 |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2006-07-18 : 16:16:21
|
Here's one without the union. It handles both null and not null.select a.Acct, a.AcctName, Contact = CASE WHEN a.AcctContact IS NULL THEN o.ordercontact ELSE a.AcctContact END, a.Addressfrom accts ainner join orders oon a.acct = o.acctinner join( select o2.acct, max(o2.orderdate) as orderdate from orders o2 inner join accts a2 on a2.Acct = o2.Acct group by o2.acct) ton o.acct = t.acct and o.orderdate = t.orderdate Tara Kizer |
 |
|
|
Hommer
Aged Yak Warrior
808 Posts |
Posted - 2006-07-18 : 16:17:03
|
| Great! It works, but it is way complicated than I thought. When I throw this with my other half dozen requirements/solutions, I don't think I can follow through the maze.Let me try.Thanks a lot! |
 |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2006-07-18 : 16:45:23
|
quote: Originally posted by humanpuck Try putting it in a having clause.select AcctName, Address, AcctContact, OrderContactfrom Accts join Orders on Accts.Acct=Orders.Acctgroup by AcctName, Address, AcctContact, OrderContacthaving OrderDate = max(OrderDate)union allselect '','','',ordercontactfrom orders awhere not exists ( select OrderContactfrom Accts join Orders b on Accts.Acct=Orders.Acctwhere a.ordercontact = b.ordercontactgroup by OrderContacthaving OrderDate = max(OrderDate))group by ordercontacthaving orderdate = max(orderdate)
I can't get this solution to work with the DDL provided by Hommer.Tara Kizer |
 |
|
|
humanpuck
Yak Posting Veteran
94 Posts |
Posted - 2006-07-18 : 16:52:42
|
| sorry bout that try thisselect AcctName, Address, case when AcctContact is null then OrderContact else acctcontact end as Contactfrom Accts inner join Orders on Accts.Acct=Orders.Acctgroup by AcctName, Address, AcctContact, OrderContacthaving max(OrderDate) = (select max(orderdate) from orders) |
 |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2006-07-18 : 16:56:08
|
quote: Originally posted by humanpuck sorry bout that try thisselect AcctName, Address, AcctContact, OrderContactfrom Accts inner join Orders on Accts.Acct=Orders.Acctgroup by AcctName, Address, AcctContact, OrderContacthaving max(OrderDate) = (select max(orderdate) from orders)
It now no longer blows up with a syntax error, but it also doesn't provide the expected result set Hommer posted. Check this out:CREATE TABLE [dbo].[Accts] ([Acct] [int] NULL ,[AcctName] [nvarchar] (50) NULL ,[AcctContact] [nvarchar] (50) NULL ,[Address] [nvarchar] (50) NULL ) ON [PRIMARY]CREATE TABLE [dbo].[Orders] ([OrderID] [int] NULL ,[Acct] [int] NULL ,[OrderDate] [smalldatetime] NULL ,[OrderContact] [nvarchar] (50) NULL ) ON [PRIMARY]insert into accts values(1,'ABC', 'Jeff', '123 Main')insert into accts values(2,'Zipz',NULL,'3221 Wall')insert into Orders values(1,1, '2005-01-01 ','Whos who')insert into Orders values(2,2, '2005-01-01 ', 'Well')insert into Orders values(3,2,'2006-02-01 ','Got it')select AcctName, Address, AcctContact, OrderContactfrom Accts join Orders on Accts.Acct=Orders.Acctgroup by AcctName, Address, AcctContact, OrderContacthaving max(OrderDate) = (select max(orderdate) from orders)drop table accts, orders Here's his expected result set:1 ABC Jeff 123 Main2 Zipz Got it 3221 WallTara Kizer |
 |
|
|
humanpuck
Yak Posting Veteran
94 Posts |
Posted - 2006-07-18 : 17:00:21
|
| select AcctName, Address, case when AcctContact is null then OrderContact else acctcontact end as Contactfrom Accts inner join Orders on Accts.Acct=Orders.Acctgroup by AcctName, Address, AcctContact, OrderContacthaving max(OrderDate) = (select max(orderdate) from orders)union allselect acctname, address, acctcontactfrom Accts inner join Orders on Accts.Acct=Orders.Acctwhere acctcontact is not nullthis works I didn't notice the results that were wanted |
 |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2006-07-18 : 17:02:25
|
| Welcome to the club humanpuck! Hommer, now you'll need to compare the second solution that I posted to the other solutions here to see which has the better execution plan.Tara Kizer |
 |
|
|
|
|
|
|
|