Skip to content
Advertisement

Combine ORDER BY and GROUP BY and a counter

I use this SQL query to get customer order lines from an imported CSV file

select * from tblorderlines
where ordernr in (select ordernr from tblorderlines where linetype = 'H')
order by ordernr

and get this result

id      date         ordernr   customer     customerid  
7608    2020-06-15   77654     Customer 1   1111
7609    2020-06-15   77655     Customer 2   2222
7610    2020-06-16   77656     Customer 3   3333
7611    2020-06-16   77657     Customer 1   1111
7612    2020-06-16   77658     Customer 4   4444

Now I would like to produce 2 different results, where one, in addition to order by ordernr also group them by their customerid

id      date         ordernr   customer     customerid  
7608    2020-06-15   77654     Customer 1   1111
7611    2020-06-16   77657     Customer 1   1111
7609    2020-06-15   77655     Customer 2   2222
7610    2020-06-16   77656     Customer 3   3333
7612    2020-06-16   77658     Customer 4   4444

and another where I get a counter (the cnt column) with how many times a customer/customerid occurs

id      date         ordernr   customer     customerid   cnt
7608    2020-06-15   77654     Customer 1   1111         2
7609    2020-06-15   77655     Customer 2   2222         1
7610    2020-06-16   77656     Customer 3   3333         1
7611    2020-06-16   77657     Customer 1   1111         2
7612    2020-06-16   77658     Customer 4   4444         1

I’ve tried several join and group by solutions, though my SQL skills aren’t good enough to get me these results.

Advertisement

Answer

You can just order by customer prior to ordernr to group the values, and use COUNT as a window function to get the count of each customerid. Combining both in one query (and considering your initial query as a view):

SELECT *,
       COUNT(*) OVER (PARTITION BY customerid) AS cnt
FROM tblorderview
ORDER BY customer, ordernr

Output (based on the results of your original query):

id      date        ordernr     customer    customerid  cnt
7608    2020-06-15  77654       Customer 1  1111        2
7611    2020-06-16  77657       Customer 1  1111        2
7609    2020-06-15  77655       Customer 2  2222        1
7610    2020-06-16  77656       Customer 3  3333        1
7612    2020-06-16  77658       Customer 4  4444        1

Demo on SQLFiddle

Update

Based on discussion in comments, the ordering actually needs to be done so that all a customers orders are grouped together and sorted into the list based on the minimum order number for that customer. This can be done with this query:

SELECT *,
       COUNT(*) OVER (PARTITION BY customerid) AS cnt
FROM tblorderview
ORDER BY MIN(ordernr) OVER (PARTITION BY customerid),
         ordernr

Output (for the expanded demo):

id      date        ordernr     customer    customerid  cnt
7608    2020-06-15  77654       Customer 8  8888        1
7609    2020-06-15  77655       Customer 7  7777        2
7615    2020-06-17  77661       Customer 7  7777        2
7610    2020-06-16  77656       Customer 6  6666        1
7611    2020-06-16  77657       Customer 5  5555        1
7612    2020-06-16  77658       Customer 4  4444        2
7617    2020-06-18  77663       Customer 4  4444        2
7613    2020-06-17  77659       Customer 3  3333        1
7614    2020-06-17  77660       Customer 2  2222        1
7616    2020-06-18  77662       Customer 1  1111        1

Demo on SQLFiddle

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement