Discussions
Categories
- 197K All Categories
- 2.5K Data
- 546 Big Data Appliance
- 1.9K Data Science
- 450.8K Databases
- 221.9K General Database Discussions
- 3.8K Java and JavaScript in the Database
- 31 Multilingual Engine
- 552 MySQL Community Space
- 479 NoSQL Database
- 7.9K Oracle Database Express Edition (XE)
- 3.1K ORDS, SODA & JSON in the Database
- 555 SQLcl
- 4K SQL Developer Data Modeler
- 187.2K SQL & PL/SQL
- 21.4K SQL Developer
- 296.3K Development
- 17 Developer Projects
- 139 Programming Languages
- 293K Development Tools
- 110 DevOps
- 3.1K QA/Testing
- 646.1K Java
- 28 Java Learning Subscription
- 37K Database Connectivity
- 158 Java Community Process
- 105 Java 25
- 22.1K Java APIs
- 138.2K Java Development Tools
- 165.3K Java EE (Java Enterprise Edition)
- 19 Java Essentials
- 162 Java 8 Questions
- 86K Java Programming
- 81 Java Puzzle Ball
- 65.1K New To Java
- 1.7K Training / Learning / Certification
- 13.8K Java HotSpot Virtual Machine
- 94.3K Java SE
- 13.8K Java Security
- 205 Java User Groups
- 24 JavaScript - Nashorn
- Programs
- 468 LiveLabs
- 39 Workshops
- 10.2K Software
- 6.7K Berkeley DB Family
- 3.5K JHeadstart
- 5.7K Other Languages
- 2.3K Chinese
- 175 Deutsche Oracle Community
- 1.1K Español
- 1.9K Japanese
- 233 Portuguese
Get the earliest date for a customer order

I have the following setup and I'm trying to get the earliest order_date for each customer but my CTE is giving me a syntax error, which I can't seem to resolve. Any help would be greatly appreciated.
CREATE TABLE customers(customer_id, customer_name, join_date) AS SELECT 1, 'ABC', DATE '2020-05-20' FROM DUAL UNION ALL SELECT 2, 'XYZ', DATE '2020-04-03' FROM DUAL; CREATE TABLE products(product_id, product_name) AS SELECT 1, 'Coca Cola' FROM DUAL UNION ALL SELECT 1, 'Dr. Pepper' FROM DUAL UNION ALL SELECT 3, 'Pepsi' FROM DUAL; CREATE TABLE sales(customer_id, product_id, order_date) AS SELECT 1, 1, DATE '2021-11-20' FROM DUAL UNION ALL SELECT 1, 2, DATE '2021-11-21' FROM DUAL UNION ALL SELECT 1, 3, DATE '2021-11-22' FROM DUAL UNION ALL SELECT 2, 1, DATE '2021-12-23' FROM DUAL UNION ALL SELECT 2, 2, DATE '2021-12-21' FROM DUAL UNION ALL SELECT 2, 3, DATE '2021-12-22' FROM DUAL;
WITH cte AS ( SELECT s.customer_id ,c.customer_name ,s.product_id ,p.product_name ,s.order_date RANK() OVER (PARTITION BY s.customer_id ORDER BY s.order_date) rnk FROM sales s ,customers c ,products p INNER JOIN customers c ON s.customer_id = c.customer_id INNER JOIN products p ON s.product_id = p.product_id ) SELECT customer_id ,customer_name ,product_id ,product_name ,order_date FROM cte WHERE rnk = 1;
Best Answer
-
- comma is missing before RANK
- you join same tables twice - once using native joins and then second time using ANSI joins
All works as inteneded after fixing it:
WITH CTE AS ( SELECT S.CUSTOMER_ID, C.CUSTOMER_NAME, S.PRODUCT_ID, P.PRODUCT_NAME, S.ORDER_DATE, RANK() OVER (PARTITION BY S.CUSTOMER_ID ORDER BY S.ORDER_DATE) RNK FROM SALES S, CUSTOMERS C, PRODUCTS P WHERE S.CUSTOMER_ID = C.CUSTOMER_ID AND S.PRODUCT_ID = P.PRODUCT_ID ) SELECT CUSTOMER_ID, CUSTOMER_NAME, PRODUCT_ID, PRODUCT_NAME, ORDER_DATE FROM CTE WHERE RNK = 1 / CUSTOMER_ID CUS PRODUCT_ID PRODUCT_NA ORDER_DAT ----------- --- ---------- ---------- --------- 1 ABC 1 Coca Cola 20-NOV-21 1 ABC 1 Dr. Pepper 20-NOV-21 2 XYZ 3 Pepsi 22-DEC-21 SQL>
SY.
Answers
-
Hi, @User_G3NSO
Thanks for posting the CREATE TABLE statements; that's very helpful! Don't forget to post the exact results you want from the given sample data.
You're missing a comma in the first SELECT clause, between the last two columns (order_date and rnk). Also, you're mixing up the two ways of doing joins. If you're using the ANSI join syntax (with the keyword JOIN between tables), then don't use the older syntax (with a comma between tables).
If you fix those errors, like this:
WITH cte AS ( SELECT s.customer_id ,c.customer_name ,s.product_id ,p.product_name ,s.order_date ,RANK() OVER (PARTITION BY s.customer_id ORDER BY s.order_date) rnk FROM sales s INNER JOIN customers c ON s.customer_id = c.customer_id INNER JOIN products p ON s.product_id = p.product_id ) SELECT customer_id ,customer_name ,product_id ,product_name ,order_date FROM cte WHERE rnk = 1 ORDER BY customer_id -- or whatever you want ;
then you'll get these results:
CUSTOMER_ID CUS PRODUCT_ID PRODUCT_NA ORDER_DATE --------------- --- ---------- ---------- ----------- 1 ABC 1 Coca Cola 20-Nov-2021 1 ABC 1 Dr. Pepper 20-Nov-2021 2 XYZ 3 Pepsi 22-Dec-2021
Is that what you want?
-
- comma is missing before RANK
- you join same tables twice - once using native joins and then second time using ANSI joins
All works as inteneded after fixing it:
WITH CTE AS ( SELECT S.CUSTOMER_ID, C.CUSTOMER_NAME, S.PRODUCT_ID, P.PRODUCT_NAME, S.ORDER_DATE, RANK() OVER (PARTITION BY S.CUSTOMER_ID ORDER BY S.ORDER_DATE) RNK FROM SALES S, CUSTOMERS C, PRODUCTS P WHERE S.CUSTOMER_ID = C.CUSTOMER_ID AND S.PRODUCT_ID = P.PRODUCT_ID ) SELECT CUSTOMER_ID, CUSTOMER_NAME, PRODUCT_ID, PRODUCT_NAME, ORDER_DATE FROM CTE WHERE RNK = 1 / CUSTOMER_ID CUS PRODUCT_ID PRODUCT_NA ORDER_DAT ----------- --- ---------- ---------- --------- 1 ABC 1 Coca Cola 20-NOV-21 1 ABC 1 Dr. Pepper 20-NOV-21 2 XYZ 3 Pepsi 22-DEC-21 SQL>
SY.
-
-
I just noticed you have 2 products with same id of 1. I assume it was a typo and it should be:
CREATE TABLE products(product_id, product_name) AS SELECT 1, 'Coca Cola' FROM DUAL UNION ALL SELECT 2, 'Dr. Pepper' FROM DUAL UNION ALL SELECT 3, 'Pepsi' FROM DUAL; WITH CTE AS ( SELECT S.CUSTOMER_ID, C.CUSTOMER_NAME, S.PRODUCT_ID, P.PRODUCT_NAME, S.ORDER_DATE, RANK() OVER (PARTITION BY S.CUSTOMER_ID ORDER BY S.ORDER_DATE) RNK FROM SALES S, CUSTOMERS C, PRODUCTS P WHERE S.CUSTOMER_ID = C.CUSTOMER_ID AND S.PRODUCT_ID = P.PRODUCT_ID ) SELECT CUSTOMER_ID, CUSTOMER_NAME, PRODUCT_ID, PRODUCT_NAME, ORDER_DATE FROM CTE WHERE RNK = 1 / CUSTOMER_ID CUS PRODUCT_ID PRODUCT_NA ORDER_DAT ----------- --- ---------- ---------- --------- 1 ABC 1 Coca Cola 20-NOV-21 2 XYZ 2 Dr. Pepper 21-DEC-21 SQL>
SY.