Apologies, this is similar to a question a recently asked and was answered.
I have a query below that is tracking customer purchases by the hour in order to determine when a customer is likely to place an order.
The query appears to be working fine but I’m stuck with a few issues and I’m looking for help.
First, instead of output of NULLS I want to display 0 (zero) for those hours a purchase wasn’t made. I think COALESCE() is the right way to proceed but ran into syntax errors.
Secondly, I want to display the customers FIRST_NAME, LAST_NAME after the customer_id and the total purchases after hour 23 for each customer_id. I am thinking LEFT JOIN as I want to display customers that have no purchases too. In my test CASE below that would be customer_id 2.
Below is my test CASE and sample data. As always, if there is a better or simpler way to code this I would appreciate any input.
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'DD-MON-YYYY HH24:MI:SS.FF';
CREATE TABLE customers (CUSTOMER_ID, FIRST_NAME, LAST_NAME) AS
SELECT 1, 'Faith', 'Aaron' FROM DUAL UNION ALL
SELECT 2, 'Lisa', 'Jones' FROM DUAL UNION ALL
SELECT 3, 'Roz', 'Doyle' FROM DUAL;
create table purchases(
ORDER_ID NUMBER GENERATED BY DEFAULT AS IDENTITY (START WITH 1) NOT NULL,
customer_id number,
PRODUCT_ID NUMBER,
QUANTITY NUMBER,
purchase_date timestamp
);
insert into purchases (customer_id, product_id, quantity, purchase_date)
select 1 customer_id, 102 product_id, 1 quantity,
TIMESTAMP '2024-04-03 00:00:00' + INTERVAL '23:27' HOUR TO MINUTE + ((LEVEL-1) * INTERVAL '1 00:00:01' DAY TO SECOND) * -1 + ((LEVEL-1) * interval '0.007125' second)
as purchase_date
from dual
connect by level <= 3 UNION all
select 1, 101, 1,
TIMESTAMP '2024-05-10 00:00:57' + INTERVAL '07:17' HOUR TO MINUTE + ((LEVEL-1) * INTERVAL '1 00:00:01' DAY TO SECOND) * -1 + ((LEVEL-1) * interval '0.000120' second)
from dual
connect by level <= 2 UNION all
select 1, 101, 1,
TIMESTAMP '2024-06-13 00:00:59.999999' + INTERVAL '23:14' HOUR TO MINUTE + ((LEVEL-1) * INTERVAL '1 00:00:00' DAY TO SECOND) * -1 + ((LEVEL-1) * interval '0.999999' second)
from dual
connect by level <= 1 UNION all
select 3, 100, 1,
TIMESTAMP '2024-06-16 00:00:00.888999' + INTERVAL '00:37' HOUR TO MINUTE + ((LEVEL-1) * INTERVAL '1 00:00:00' DAY TO SECOND) * -1 + ((LEVEL-1) * interval '0.999999' second)
from dual
connect by level <= 1 UNION all
select 3, 103, 3,
TIMESTAMP '2024-06-09 00:00:00' + INTERVAL '17:37' HOUR TO MINUTE + ((LEVEL-1) * INTERVAL '1 00:00:00' DAY TO SECOND) * -1 + ((LEVEL-1) * interval '0.009120' second)
from dual
connect by level <= 6;
SELECT *
FROM
(
SELECT
customer_id,
SUBSTR(TO_CHAR(PURCHASE_DATE ,'HH24'),1,2) tm
FROM purchases)
PIVOT
(
SUM (1)
FOR TM IN ('00','01','02','03','04','05','06','07','08','09','10','11','12','13','14','15','16','17','18','19','20','21','22','23'
)
) pv
ORDER BY customer_id;