Solved

SQL Query to Find The First Order For All Customers

Posted on 2010-09-15
17
859 Views
Last Modified: 2012-05-10
I have a table like this:

-order_id
-order_date
-user_id

For each user, I want to find their *first* order only.  order_id is an auto increment and order_date is datetime.  Lowest ID or earliest date would be their first order.
0
Comment
Question by:trippy1976
  • 9
  • 4
  • 3
  • +1
17 Comments
 
LVL 7

Expert Comment

by:tlovie
ID: 33684601
SELECT user_id, min(order_date) as min_order_date
FROM table
GROUP BY user_id
0
 
LVL 7

Expert Comment

by:tlovie
ID: 33684614
or you can do this:

SELECT user_id, min(order_id) as min_order_id
FROM table
GROUP BY user_id
0
 
LVL 4

Author Comment

by:trippy1976
ID: 33684789
Excellent, thank you.  Before I close this can I impose for one more quickie?

I'd like to know how many customers made their first order in each month/year

Select count(min(order_id)) as total_orders, MONTH(order_date) as order_month, YEAR(order_date) as order_year
from table
group by user_id
order by order_year, order_month asc

??  Am I close?  

Thanks!
0
What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

 
LVL 142

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 33684813
this article can help to write the query you want:http://www.experts-exchange.com/A_3203.html
0
 
LVL 7

Expert Comment

by:tlovie
ID: 33684872
count, sum, avg, min, max are called aggregate functions.  you cannot have them in your group by clause.  MONTH, YEAR, etc, are scalar functions, so if they are in your select statement, they must also be in your group by clause.

I'm not sure if you still want user_id in there, but it could be in our out.... if you want to take it out, you would remove it from the SELECT and the GROUP BY clauses.

select user_id, count(order_id), MONTH(order_date) as order_month, YEAR(order_date) as order_year
from table
group by user_id, MONTH(order_date), YEAR(order_date)
order by order_year, order_month asc
0
 
LVL 4

Author Comment

by:trippy1976
ID: 33686019
Thanks for the great replies tlovie, but maybe I confused by trying it myself.  

What I want is only a count of the orders made in a month that are that customer's *first* order.

The first query shows each first order with the date, but I get something like :

1   9/1/2010
2  9/2/2010
3  9/3/2010

etc.

Where col 1 is the order_id and col 2 is the date of the order.  This is great.

Now I'd like something like:

3  9   2010

Where col1 is the total first time orders in month 9 (col2) of 2010 (col3)

Is this doable in a single query?
0
 
LVL 19

Expert Comment

by:NerdsOfTech
ID: 33687058
Like tloive said if you want to NOT GROUP BY user_id just take it out of both the select and group by areas.

Also I think year should group out first - altered SQL below:
select count(order_id), MONTH(order_date) as order_month, YEAR(order_date) as order_year
from table
group YEAR(order_date), MONTH(order_date)
order by order_year, order_month asc

Open in new window

0
 
LVL 19

Expert Comment

by:NerdsOfTech
ID: 33687074
however this give you ALL orders.

try something that will give you a count of the MINIMUMs

try this and see if we get any errors:
select user_id, YEAR(order_date) as order_year, MONTH(order_date) as order_month, SUM(IF(MIN(order_id) <> NULL, 1, 0)) as first_orders
from table
group by user_id, YEAR(order_date), MONTH(order_date), order_date
order by order_year, order_month asc

Open in new window

0
 
LVL 19

Expert Comment

by:NerdsOfTech
ID: 33687078
oops i mean try:
select user_id, YEAR(order_date) as order_year, MONTH(order_date) as order_month, SUM(IF(MIN(order_id) <> NULL, 1, 0)) as first_orders
from table
group by user_id, YEAR(order_date), MONTH(order_date)
order by order_year, order_month asc

Open in new window

0
 
LVL 19

Expert Comment

by:NerdsOfTech
ID: 33687108
then you can SUPER-query the results:

here is an example of trippy1976's query w/ SUPER-QUERY
SELECT SUM(first_orders), order_year, order_month FROM (
Select count(min(order_id)) as first_orders, MONTH(order_date) as order_month, YEAR(order_date) as order_year
from table
group by user_id, order_year, order_month
order by order_date asc
) x
group by order_year, order_month

Open in new window

0
 
LVL 19

Expert Comment

by:NerdsOfTech
ID: 33687116
fixed
SELECT SUM(first_orders), order_year, order_month FROM (
Select count(min(order_id)) as first_orders, MONTH(order_date) as order_month, YEAR(order_date) as order_year
from table
group by user_id, order_year, order_month
order by order_year, order_month asc
) x
group by order_year, order_month

Open in new window

0
 
LVL 7

Accepted Solution

by:
tlovie earned 500 total points
ID: 33687122
Okay, I think I understand what you want..

Step 1:

select user_id, min(order_date) as min_order_date from table group by user_id
-- this gives us the date that each customer orders a product

Step 2:

select count(user_id), MONTH(min_order_date), YEAR(min_order_date) from (
select user_id, min(order_date) as min_order_date from table group by user_id ) as q
group by MONTH(min_order_date), YEAR(min_order_date)
-- use the step 1 subquery to find all the new customers by month

Give that a go... all you need to execute is the step 2 query.
0
 
LVL 19

Expert Comment

by:NerdsOfTech
ID: 33687129
nm order_date should sort
fixed.:
SELECT SUM(first_orders), order_year, order_month FROM (
Select count(min(order_id)) as first_orders, MONTH(order_date) as order_month, YEAR(order_date) as order_year
from table
group by user_id, order_year, order_month
order by order_date asc
) x
group by order_year, order_month

Open in new window

0
 
LVL 19

Expert Comment

by:NerdsOfTech
ID: 33687181
fixed min parameter. try:
SELECT 
 SUM(first_orders) AS total_first_orders, 
 order_year, 
 order_month 
FROM 
(
 SELECT 
  COUNT(MIN(order_date)) AS first_orders, 
  MONTH(order_date) AS order_month, 
  YEAR(order_date) AS order_year
 FROM table
 GROUP BY user_id, YEAR(order_date), MONTH(order_date) 
 ORDER BY order_date ASC
) x
GROUP BY order_year ASC, order_month ASC

Open in new window

0
 
LVL 19

Expert Comment

by:NerdsOfTech
ID: 33687212
the inner query selects first orders from EACH month from EACH customer.

say there is 3 customers:

first_order count|month|year

1|9|2010
1|10|2010
1|11|2010

1|9|2010
0|10|2010
1|11|2010

1|9|2010
0|10|2010
1|11|2010

Then the UPPER or SUPER query will take totals of matching year, month totals you end up with:

total first orders|year|month
3|2010|9
1|2010|10
3|2010|11
0
 
LVL 4

Author Closing Comment

by:trippy1976
ID: 33691674
Perfect on both counts, thanks!
0
 
LVL 19

Expert Comment

by:NerdsOfTech
ID: 33696907
Thanks for the feedback. Which query did you end up using in the end?
0

Featured Post

What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction In this installment of my SQL tidbits, I will be looking at parsing Extensible Markup Language (XML) directly passed as string parameters to MySQL 5.1.5 or higher. These would be instances where LOAD_FILE (http://dev.mysql.com/doc/refm…
Password hashing is better than message digests or encryption, and you should be using it instead of message digests or encryption.  Find out why and how in this article, which supplements the original article on PHP Client Registration, Login, Logo…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

832 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