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 |
|
BobRoberts
Posting Yak Master
109 Posts |
Posted - 2011-12-12 : 10:42:26
|
| [code]In this example I need to find the top 2 customers with the most transactions and display the associated customer name.SELECT TOP 2 TBL_SLS_TRANSACT.customer_id, TBL_CUSTOMERS.customer_name, COUNT(TBL_SLS_TRANSACT.customer_id) AS NumberOfTransactionsFROM TBL_SLS_TRANSACT INNER JOIN TBL_CUSTOMERS ON TBL_SLS_TRANSACT.customer_id = TBL_CUSTOMERS.customer_idGROUP BY TBL_SLS_TRANSACT.customer_id, TBL_CUSTOMERS.customer_nameORDER BY COUNT(TBL_SLS_TRANSACT.customer_id) DESC-------------------------------------------------TBL_SLS_TRANSACT:customer_id|transaction_id|transaction_amt111111 728172 22.4000222222 282838 180.9100222222 372727 55.1000222222 412123 18.5200333333 573838 331.2500333333 459282 44.7100TBL_CUSTOMERS:customer_id|customer_name| visit_date111111 Jason Riverson 2011-05-30 00:00:00222222 Tiara Pelican 2011-09-12 00:00:00333333 Sid Seleasa 2011-07-05 00:00:00Running the above script yields:customer_id|customer_name| NumberOfTransactions222222 Tiara Pelican 3333333 Sid Seleasa 2But when the TBL_CUSTOMERS changes to...customer_id|customer_name| visit_date111111 Jason Riverson 2011-05-30 00:00:00222222 Tiara Pelican 2011-09-12 00:00:00333333 Sid Seleasa 2011-07-05 00:00:00222222 Tiara Pelican 2011-10-17 00:00:00222222 Tiara Pelican 2011-11-03 00:00:00222222 Tiara Pelican 2011-12-20 00:00:00...the script yields:customer_id|customer_name| NumberOfTransactions222222 Tiara Pelican 12333333 Sid Seleasa 2I realize why this is happening, and know that it's a common difficulty, and have tried a few things, but have been unable to find a specific adjustment that will display the customer name while displaying the correct number of transactions for each customer. The customer name will never vary with each visit, and so I don't really care which customer name is displayed. It's too bad SQL doesn't have an INNER SINGLE JOIN - that would make sense and be very helpful.Here's a script to create the two tables, followed by a script to create the second version of the TBL_CUSTOMERS table.--------------------------------------USE [Northwind]GO/****** Object: Table [dbo].[TBL_SLS_TRANSACT] Script Date: 12/09/2011 14:25:36 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOSET ANSI_PADDING ONGOCREATE TABLE [dbo].[TBL_SLS_TRANSACT]( [customer_id] [varchar](6) NULL, [transaction_id] [varchar](10) NULL, [transaction_amt] [money] NULL) ON [PRIMARY]GOSET ANSI_PADDING OFFGOINSERT [dbo].[TBL_SLS_TRANSACT] ([customer_id], [transaction_id], [transaction_amt]) VALUES (N'111111', N'728172', 22.4000)INSERT [dbo].[TBL_SLS_TRANSACT] ([customer_id], [transaction_id], [transaction_amt]) VALUES (N'222222', N'282838', 180.9100)INSERT [dbo].[TBL_SLS_TRANSACT] ([customer_id], [transaction_id], [transaction_amt]) VALUES (N'222222', N'372727', 55.1000)INSERT [dbo].[TBL_SLS_TRANSACT] ([customer_id], [transaction_id], [transaction_amt]) VALUES (N'222222', N'412123', 18.5200)INSERT [dbo].[TBL_SLS_TRANSACT] ([customer_id], [transaction_id], [transaction_amt]) VALUES (N'333333', N'573838', 331.2500)INSERT [dbo].[TBL_SLS_TRANSACT] ([customer_id], [transaction_id], [transaction_amt]) VALUES (N'333333', N'459282', 44.7100)/****** Object: Table [dbo].[TBL_CUSTOMERS] Script Date: 12/09/2011 14:25:36 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOSET ANSI_PADDING ONGOCREATE TABLE [dbo].[TBL_CUSTOMERS]( [customer_id] [varchar](6) NULL, [customer_name] [varchar](20) NULL, [visit_date] [smalldatetime] NULL) ON [PRIMARY]GOSET ANSI_PADDING OFFGOINSERT [dbo].[TBL_CUSTOMERS] ([customer_id], [customer_name], [visit_date]) VALUES (N'111111', N'Jason Riverson', CAST(0x9EF30000 AS SmallDateTime))INSERT [dbo].[TBL_CUSTOMERS] ([customer_id], [customer_name], [visit_date]) VALUES (N'222222', N'Tiara Pelican', CAST(0x9F5C0000 AS SmallDateTime))INSERT [dbo].[TBL_CUSTOMERS] ([customer_id], [customer_name], [visit_date]) VALUES (N'333333', N'Sid Seleasa', CAST(0x9F170000 AS SmallDateTime))---------------------------------------USE [Northwind]GO/****** Object: Table [dbo].[TBL_CUSTOMERS] Script Date: 12/09/2011 16:17:18 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOSET ANSI_PADDING ONGOCREATE TABLE [dbo].[TBL_CUSTOMERS]( [customer_id] [varchar](6) NULL, [customer_name] [varchar](20) NULL, [visit_date] [smalldatetime] NULL) ON [PRIMARY]GOSET ANSI_PADDING OFFGOINSERT [dbo].[TBL_CUSTOMERS] ([customer_id], [customer_name], [visit_date]) VALUES (N'111111', N'Jason Riverson', CAST(0x9EF30000 AS SmallDateTime))INSERT [dbo].[TBL_CUSTOMERS] ([customer_id], [customer_name], [visit_date]) VALUES (N'222222', N'Tiara Pelican', CAST(0x9F5C0000 AS SmallDateTime))INSERT [dbo].[TBL_CUSTOMERS] ([customer_id], [customer_name], [visit_date]) VALUES (N'333333', N'Sid Seleasa', CAST(0x9F170000 AS SmallDateTime))INSERT [dbo].[TBL_CUSTOMERS] ([customer_id], [customer_name], [visit_date]) VALUES (N'222222', N'Tiara Pelican', CAST(0x9F7F0000 AS SmallDateTime))INSERT [dbo].[TBL_CUSTOMERS] ([customer_id], [customer_name], [visit_date]) VALUES (N'222222', N'Tiara Pelican', CAST(0x9F900000 AS SmallDateTime))INSERT [dbo].[TBL_CUSTOMERS] ([customer_id], [customer_name], [visit_date]) VALUES (N'222222', N'Tiara Pelican', CAST(0x9FBF0000 AS SmallDateTime))--------------------------------------[/code] |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2011-12-12 : 10:45:38
|
for new scenario make code likeSELECT TOP 2 TBL_SLS_TRANSACT.customer_id, c.customer_name, COUNT(TBL_SLS_TRANSACT.customer_id) AS NumberOfTransactionsFROM TBL_SLS_TRANSACT INNER JOIN (SELECT customer_id,customer_name FROM TBL_CUSTOMERS GROUP BY customer_id,customer_name)cON TBL_SLS_TRANSACT.customer_id = c.customer_idGROUP BY TBL_SLS_TRANSACT.customer_id, c.customer_nameORDER BY COUNT(TBL_SLS_TRANSACT.customer_id) DESC ------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
BobRoberts
Posting Yak Master
109 Posts |
Posted - 2011-12-12 : 11:31:36
|
Thanks very much - this is exactly what I needed. I attempted something similar, but didn't follow through with the alias "c" as you have done.quote: Originally posted by visakh16 for new scenario make code likeSELECT TOP 2 TBL_SLS_TRANSACT.customer_id, c.customer_name, COUNT(TBL_SLS_TRANSACT.customer_id) AS NumberOfTransactionsFROM TBL_SLS_TRANSACT INNER JOIN (SELECT customer_id,customer_name FROM TBL_CUSTOMERS GROUP BY customer_id,customer_name)cON TBL_SLS_TRANSACT.customer_id = c.customer_idGROUP BY TBL_SLS_TRANSACT.customer_id, c.customer_nameORDER BY COUNT(TBL_SLS_TRANSACT.customer_id) DESC ------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/
|
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2011-12-12 : 11:37:02
|
no problemyou're wc ------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
BobRoberts
Posting Yak Master
109 Posts |
Posted - 2011-12-19 : 12:53:15
|
| [code]I got an additional twist on the same problem. I need to display the customer's most recent telephone number from the TBL_CUSTOMER_TELEPHONE_CHANGES table, which can be represented as this:TBL_CUSTOMER_TELEPHONE_CHANGES:customer_id|date_of_change|telephone_number111111 2010-03-12 6305551234111111 2010-09-01 3128728483222222 2010-07-07 3178872737333333 2010-10-01 6307772323333333 2010-05-05 3171234567I thought that intuitively I could add another INNER JOIN clause immediately after the first, but the great SQL god will not allow that, complaining of various syntac errors with whatever I try.Below is the script that works that I need to modify to display the latest telephone number for the customer:SELECT TOP 2 TBL_SLS_TRANSACT.customer_id, c.customer_name, COUNT(TBL_SLS_TRANSACT.customer_id) AS NumberOfTransactionsFROM TBL_SLS_TRANSACT INNER JOIN (SELECT customer_id,customer_name FROM TBL_CUSTOMERS GROUP BY customer_id,customer_name)cON TBL_SLS_TRANSACT.customer_id = c.customer_idGROUP BY TBL_SLS_TRANSACT.customer_id, c.customer_nameORDER BY COUNT(TBL_SLS_TRANSACT.customer_id) DESC Here is the script used to create the TBL_CUSTOMER_TELEPHONE_CHANGES table.USE [Northwind]GO/****** Object: Table [dbo].[TBL_CUSTOMER_TELEPHONE_CHANGES] Script Date: 12/19/2011 10:28:23 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOSET ANSI_PADDING ONGOCREATE TABLE [dbo].[TBL_CUSTOMER_TELEPHONE_CHANGES]( [Customer_ID] [varchar](6) NULL, [Date_of_Change] [smalldatetime] NULL, [Telephone_number] [nchar](10) NULL) ON [PRIMARY]GOSET ANSI_PADDING OFFGOINSERT [dbo].[TBL_CUSTOMER_TELEPHONE_CHANGES] ([Customer_ID], [Date_of_Change], [Telephone_number]) VALUES (N'111111', CAST(0x9D370000 AS SmallDateTime), N'6305551234')INSERT [dbo].[TBL_CUSTOMER_TELEPHONE_CHANGES] ([Customer_ID], [Date_of_Change], [Telephone_number]) VALUES (N'111111', CAST(0x9DE40000 AS SmallDateTime), N'3128728483')INSERT [dbo].[TBL_CUSTOMER_TELEPHONE_CHANGES] ([Customer_ID], [Date_of_Change], [Telephone_number]) VALUES (N'222222', CAST(0x9DAC0000 AS SmallDateTime), N'3178872737')INSERT [dbo].[TBL_CUSTOMER_TELEPHONE_CHANGES] ([Customer_ID], [Date_of_Change], [Telephone_number]) VALUES (N'333333', CAST(0x9E02038F AS SmallDateTime), N'6307772323')INSERT [dbo].[TBL_CUSTOMER_TELEPHONE_CHANGES] ([Customer_ID], [Date_of_Change], [Telephone_number]) VALUES (N'333333', CAST(0x9D6D038F AS SmallDateTime), N'3171234567')[/code] |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2011-12-19 : 13:04:57
|
| [code]SELECT TOP 2 TBL_SLS_TRANSACT.customer_id, c.customer_name, COUNT(TBL_SLS_TRANSACT.customer_id) AS NumberOfTransactions,t.telephone_numberFROM TBL_SLS_TRANSACT INNER JOIN (SELECT customer_id,customer_name FROM TBL_CUSTOMERS GROUP BY customer_id,customer_name)cON TBL_SLS_TRANSACT.customer_id = c.customer_idINNER JOIN TBL_CUSTOMER_TELEPHONE_CHANGES tON t.customer_id = c.customer_id INNER JOIN (SELECT customer_id,MAX(Date_of_Change) AS LatestDate FROM TBL_CUSTOMER_TELEPHONE_CHANGES GROUP BY customer_id)t1ON t1.customer_i1d = t.customer_id AND t1.LatestDate = t.Date_of_ChangeGROUP BY TBL_SLS_TRANSACT.customer_id, c.customer_nameORDER BY COUNT(TBL_SLS_TRANSACT.customer_id) DESC [/code]------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
BobRoberts
Posting Yak Master
109 Posts |
Posted - 2011-12-20 : 16:44:34
|
Thanks for your response. When I run it, I get: "Column 'TBL_CUSTOMER_TELEPHONE_CHANGES.Telephone_number' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause."When I put the field "TBL_CUSTOMER_TELEPHONE_CHANGES.Telephone_number'"at the end of the final GROUP BY clause, I get this error: "The multi-part identifier "TBL_CUSTOMER_TELEPHONE_CHANGES.Telephone_number" could not be bound.quote: Originally posted by visakh16
SELECT TOP 2 TBL_SLS_TRANSACT.customer_id, c.customer_name, COUNT(TBL_SLS_TRANSACT.customer_id) AS NumberOfTransactions,t.telephone_numberFROM TBL_SLS_TRANSACT INNER JOIN (SELECT customer_id,customer_name FROM TBL_CUSTOMERS GROUP BY customer_id,customer_name)cON TBL_SLS_TRANSACT.customer_id = c.customer_idINNER JOIN TBL_CUSTOMER_TELEPHONE_CHANGES tON t.customer_id = c.customer_id INNER JOIN (SELECT customer_id,MAX(Date_of_Change) AS LatestDate FROM TBL_CUSTOMER_TELEPHONE_CHANGES GROUP BY customer_id)t1ON t1.customer_i1d = t.customer_id AND t1.LatestDate = t.Date_of_ChangeGROUP BY TBL_SLS_TRANSACT.customer_id, c.customer_nameORDER BY COUNT(TBL_SLS_TRANSACT.customer_id) DESC ------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/
|
 |
|
|
BobRoberts
Posting Yak Master
109 Posts |
Posted - 2011-12-21 : 11:21:09
|
I can get it to work, but the phone number it selects is not the one associated with the latest date (for Sid Seleasa):INNER JOIN (SELECT customer_id,customer_name FROM TBL_CUSTOMERS GROUP BY customer_id,customer_name)cON TBL_SLS_TRANSACT.customer_id = c.customer_idLEFT JOIN ( SELECT MAX(Date_of_Change) AS LatestDate, Date_Of_Change, customer_id, telephone_number FROM TBL_CUSTOMER_TELEPHONE_CHANGES GROUP BY Date_of_Change, customer_id, telephone_number ) CTC ON CTC.customer_id = C.customer_id AND CTC.LatestDate = CTC.Date_of_ChangeGROUP BY TBL_SLS_TRANSACT.customer_id, c.customer_name, CTC.telephone_numberORDER BY COUNT(TBL_SLS_TRANSACT.customer_id) DESC |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2011-12-21 : 11:45:17
|
please use query as suggested you should join it twice like below...INNER JOIN TBL_CUSTOMER_TELEPHONE_CHANGES tON t.customer_id = c.customer_id INNER JOIN (SELECT customer_id,MAX(Date_of_Change) AS LatestDate FROM TBL_CUSTOMER_TELEPHONE_CHANGES GROUP BY customer_id)t1ON t1.customer_i1d = t.customer_id AND t1.LatestDate = t.Date_of_Change... one for getting details and one to filter latest out of a group------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
BobRoberts
Posting Yak Master
109 Posts |
Posted - 2011-12-28 : 10:19:36
|
quote: Originally posted by visakh16 please use query as suggested you should join it twice like below...INNER JOIN TBL_CUSTOMER_TELEPHONE_CHANGES tON t.customer_id = c.customer_id INNER JOIN (SELECT customer_id,MAX(Date_of_Change) AS LatestDate FROM TBL_CUSTOMER_TELEPHONE_CHANGES GROUP BY customer_id)t1ON t1.customer_i1d = t.customer_id AND t1.LatestDate = t.Date_of_Change... one for getting details and one to filter latest out of a group------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/
The following seems to work. Is this what you had in mind?SELECT TOP 2 TBL_SLS_TRANSACT.customer_id, c.customer_name,t.telephone_number, COUNT(TBL_SLS_TRANSACT.customer_id) AS NumberOfTransactionsFROM TBL_SLS_TRANSACT INNER JOIN (SELECT customer_id,customer_name FROM TBL_CUSTOMERS GROUP BY customer_id,customer_name)cON TBL_SLS_TRANSACT.customer_id = c.customer_idINNER JOIN TBL_CUSTOMER_TELEPHONE_CHANGES tON t.customer_id = c.customer_id INNER JOIN (SELECT customer_id,MAX(Date_of_Change) AS LatestDate FROM TBL_CUSTOMER_TELEPHONE_CHANGES GROUP BY customer_id)t1ON t1.customer_id = t.customer_id AND t1.LatestDate = t.Date_of_ChangeGROUP BY TBL_SLS_TRANSACT.customer_id, c.customer_name, t.telephone_numberORDER BY COUNT(TBL_SLS_TRANSACT.customer_id) DESC |
 |
|
|
X002548
Not Just a Number
15586 Posts |
|
|
webfred
Master Smack Fu Yak Hacker
8781 Posts |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2011-12-28 : 11:36:59
|
quote: Originally posted by BobRoberts
quote: Originally posted by visakh16 please use query as suggested you should join it twice like below...INNER JOIN TBL_CUSTOMER_TELEPHONE_CHANGES tON t.customer_id = c.customer_id INNER JOIN (SELECT customer_id,MAX(Date_of_Change) AS LatestDate FROM TBL_CUSTOMER_TELEPHONE_CHANGES GROUP BY customer_id)t1ON t1.customer_i1d = t.customer_id AND t1.LatestDate = t.Date_of_Change... one for getting details and one to filter latest out of a group------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/
The following seems to work. Is this what you had in mind?SELECT TOP 2 TBL_SLS_TRANSACT.customer_id, c.customer_name,t.telephone_number, COUNT(TBL_SLS_TRANSACT.customer_id) AS NumberOfTransactionsFROM TBL_SLS_TRANSACT INNER JOIN (SELECT customer_id,customer_name FROM TBL_CUSTOMERS GROUP BY customer_id,customer_name)cON TBL_SLS_TRANSACT.customer_id = c.customer_idINNER JOIN TBL_CUSTOMER_TELEPHONE_CHANGES tON t.customer_id = c.customer_id INNER JOIN (SELECT customer_id,MAX(Date_of_Change) AS LatestDate FROM TBL_CUSTOMER_TELEPHONE_CHANGES GROUP BY customer_id)t1ON t1.customer_id = t.customer_id AND t1.LatestDate = t.Date_of_ChangeGROUP BY TBL_SLS_TRANSACT.customer_id, c.customer_name, t.telephone_numberORDER BY COUNT(TBL_SLS_TRANSACT.customer_id) DESC
Indeed thats what i meant ------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
|
|
|
|
|