I am trying 8weeksqlchallenge, and I usually work with MySQL and the error codes are quite cleaner there, but not so much on dbfiddle.com
This is my schema
CREATE SCHEMA dannys_diner;
SET search_path = dannys_diner;
CREATE TABLE sales
(
"customer_id" VARCHAR(1),
"order_date" DATE,
"product_id" INTEGER
);
INSERT INTO sales ("customer_id", "order_date", "product_id")
VALUES
('A', '2021-01-01', '1'),
('A', '2021-01-01', '2'),
('A', '2021-01-07', '2'),
('A', '2021-01-10', '3'),
('A', '2021-01-11', '3'),
('A', '2021-01-11', '3'),
('B', '2021-01-01', '2'),
('B', '2021-01-02', '2'),
('B', '2021-01-04', '1'),
('B', '2021-01-11', '1'),
('B', '2021-01-16', '3'),
('B', '2021-02-01', '3'),
('C', '2021-01-01', '3'),
('C', '2021-01-01', '3'),
('C', '2021-01-07', '3');
CREATE TABLE menu
(
"product_id" INTEGER,
"product_name" VARCHAR(5),
"price" INTEGER
);
INSERT INTO menu ("product_id", "product_name", "price")
VALUES
('1', 'sushi', '10'),
('2', 'curry', '15'),
('3', 'ramen', '12');
CREATE TABLE members
(
"customer_id" VARCHAR(1),
"join_date" DATE
);
INSERT INTO members ("customer_id", "join_date")
VALUES
('A', '2021-01-07'),
('B', '2021-01-09');
And ask was to find the first product purchased by each customer, so I thought of going with subquery with following code, but it returned
Query Error: error: syntax error at or near "SELECT"
SELECT sales.customer_id, sales.product_id
FROM dannys_diner.sales
WHERE sales.order_date = SELECT MIN(sales.order_date)
FROM dannys_diner.sales
GROUP BY sales.customer_id;
3
Answers
You need
(
and)
around the sub-query — like thisAs some have noted there might be data that would cause a problem a join solves this because you can make sure the min number is by customer_id — like this
Note if you compare a fiddle using my code
https://dbfiddle.uk/CSKDTxd6
To Joel’s answer (using a windowing function) you can see we get different results — I will return more than one row if they have the same date — his will only ever return one row. Pick which one meets your requirements:
There are two syntax errors here.
First, the subquery needs to be enclosed in parentheses. This is easily remedied.
Second, in order to be valid on the right-hand side of the equality comparison with
sales.order_date
, the subquery must be guaranteed to always return a single value. TheGROUP BY
clause in the subquery breaks this, because it allows for separate minimum order dates per customer id. This is trickier to resolve, because it means re-thinking the structure of the query.Instead, I suggest using a
row_number()
window function you to identify rows by date, and then show the product from the rows without needing a correlated per-row subquery or JOIN (in other words, it should be much faster):you can join the subqzery to get your wanted result
fiddle