create database if not exists karrys_kitchen;
use karrys_kitchen;
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');
Click Next
Select Kerrys_kitchen
Business Task :
Karry Wants to use the Data to answer Questions about his customers, especially about their
Visiting patterns , how much money they’ve spent and also which menu item are their favourite.
-- i realised that same customer has placed multiple orders.
-- we must group the data by customer_id to get total Amount for each customer.
-- i realised that there are multiple product_ids in sales for each customer group
-- it means there are multiple products or same products in Menu Table.
-- so i have to apply sum(price) for each customer_id group.
-- because the data is splitted in sales and menu table hence i have to use Join here.
# try on your own first
# here are the steps
# 1. use join to merge sales and menu table as sales.customer_id and menu.price are from both
Table.
# 2. use sum() to claculate the total sales contributed by each customer on price column.
# 3. Group the aggreagted results by customer_id.
select
s.customer_id,
sum(m.price) as total_sales
from sales s inner join menu m
on
s.product_id = m.product_id
group by s.customer_id;
# i realised that some customer(s) visited twice or more in a single Day !!
## this means to find count of days i have to use distinct on order_date so that
# duplicates are eliminated and i get the right Day Count .
# to find the count of days i must use count() function.
# i realised that there are multiple enteries for the same customer that means i have to
# group the data by customer_id to find the right count.
# Here are the Steps
# TO Determine the unique nunmber of visits for each customer utlize count(distinct
order_date))
# its important to apply the distinct keyword while caclucating the visit count to avoid duplicate
# counting of days
select customer_id ,
count(distinct order_date) as 'visit_Count'
from sales
group by customer_id;
# if i want First Item from the Menu i realised i must sort the Date by
# order_date from sales in ascending Order.
# i realised if i use dense_rank() over order_date ascending order i ll get Rank 1 for the First
# Order.
select *, dense_rank() over (order by order_date) as prank
from sales;
-- i realised that rank is not reseting or regenerating when customer_id is changing?
-- i realised that i must partition data by customer_id to see the effective ranks.
-- i fill use Common Table Expression to filter the data where ProductRank matches with 1
-- to find the First Order Placed by Customer.
# 1. Create a common Table Expression(CTE) named ordered_sales_cte.
# within CTE , create a new column 'ord_rank' and caluclate the
# row number using dense_rank() window function.
# the partition by clause divides the data by customer_id, and the
# order by clause orders teh rows within each partion by order_date
# 2. in the outer query , select the appropriate columns and apply a filter in the where clause
# to retrieve only the rows where the ord_rank column = 1 which represents the first row wihin
each
# customer_id partition.
# 3. use the gorup by clause to group the result by customer_id and product_name;
# expected answer
# Customer_ID | Product_Name
# partial Solution
select
s.customer_id,
s.order_date,
m.product_name ,
dense_rank() over ( partition by s.customer_id order by s.order_date ) 'ord_rank'
from sales s inner join menu m
on
s.product_id = m.product_id;
Where ord_rank=1
A sushi 1
A curry 1
with ordered_sales as (
select
s.customer_id,
s.order_date,
m.product_name ,
dense_rank() over ( partition by s.customer_id order by s.order_date ) 'ord_rank'
from sales s inner join menu m
on
s.product_id = m.product_id
) select customer_id, product_name ,ord_rank from ordered_sales where ord_rank=1;
with ordered_sales as (
select
s.customer_id,
s.order_date,
m.product_name ,
dense_rank() over ( partition by s.customer_id order by s.order_date ) 'ord_rank'
from sales s inner join menu m
on
s.product_id = m.product_id
) select customer_id, product_name ,ord_rank from ordered_sales where ord_rank=1
group by customer_id, product_name;
Post Coffee ☕ Topics
Please expect similar Coding Questions to improve Problem Solving using SQL.
# Karry Wants to KNOW
#
========================================================================
=====================
# What is the Most Purchased Item on the Menu and how many times was it purchased by All
Customers ?
# Purchase Data reference SALES
# Name of Product Table Reference: MENU
# Expected Output :
# Purchase_Count | ProductName
# Observations
# because the data is splited into 2 tables sales & menu u must use join here to merge table
# Fetch ProductIds from Sales and ProductNames from Menu
# group records by ProductNames and find count of(ProductIds) as purchaseCount
# sort data by purchaseCount desc order and fetch first row using limit .
select
count(s.product_id) as most_purchased_item,
m.product_name
from sales s inner join menu m
on
s.product_id = m.product_id group by m.product_name
order by most_purchased_item desc limit 1;
-- it is Simple query language..
# karry Wants to KNow
# Which item was the Most Popular for Each Customer ?
# ranking+ partitioning+ joins
# Here are the steps
# 1. Create a CTE named fav_item_cte and within CTE, join the menu table and sales table
using
# product_id column
# 2. Group results by sales.customer_id and menu.product_name and calculate the count of
menu.product_id
# occurrences for each group.
# 3. Utilize the dense_rank() window function to calculate the ranking of each sales.customer+id
partition
# based on the count of orders count(sales.customer_id) in descending order
#4. in the outer query , select the appropriate columns and apply a filter in the where clause to
retrieve only
# the rows where the rank column equals 1, representing the rows from the highest order count
# for each customer
# expected output:
# cutsomer_id | product_name | order_count
#A Ramen 3
#B Sushi 2
# Partial Query
select
s.customer_id,
m.product_name,
count(m.product_id) as order_count,
dense_rank() over (
partition by s.customer_id order by count(s.customer_id) desc) as 'rank'
from menu m inner join sales s
on
m.product_id = s.product_id
group by s.customer_id,m.product_name;
with fav_item_cte as
(
select
s.customer_id,
m.product_name,
count(m.product_id) as order_count,
dense_rank() over (
partition by s.customer_id order by count(s.customer_id) desc) as 'order_rank'
from menu m inner join sales s
on
m.product_id = s.product_id
group by s.customer_id,m.product_name
) select customer_id,product_name,order_count from fav_item_cte where order_rank=1;
create table stockprices(
dates date , price int);
insert stockprices
values
('2023-10-01',10.0),
('2023-10-02',11.0),
('2023-10-03',12.0),
('2023-10-04',13.0),
('2023-10-05',14.0);
select * from stockprices;
select dates,
price,
avg(price) over(order by dates rows between 2 preceding and current row) as ThreeDaySMA
from stockPrices;
create database if not exists karrys_kitchen;
use karrys_kitchen;
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');
show tables;
-- Task : Print Data of All the Tables 1 by 1
select * from menu;
select * from sales;
select * from members;
-- Inspect Meta Data
desc menu;
desc sales;
desc members;
-- Karry's First Question :
-- What is the Total Amount each Customer Spent at the Restaurant ?
-- Sales provides information about Customers
-- Menu provides information about Pricing of Products
select * from sales;
-- i realised that same customer has placed multiple orders.
-- we must group the data by customer_id to get total Amount for each customer.
-- i realised that there are multiple product_ids in sales for each customer group
-- it means there are multiple products or same products in Menu Table.
-- so i have to apply sum(price) for each customer_id group.
-- because the data is splitted in sales and menu table hence i have to use Join here.
# try on your own first
# here are the steps
# 1. use join to merge sales and menu table as sales.customer_id and menu.price are from both
Table.
# 2. use sum() to claculate the total sales contributed by each customer on price column.
# 3. Group the aggreagted results by customer_id.
select
s.customer_id,
sum(m.price) as total_sales
from sales s inner join menu m
on
s.product_id = m.product_id
group by s.customer_id;
## Karry Wants to Know
# How many Days has Each Customer Visited the Restaurant ?
# which table provides customer visit details ? Sales.
select * from sales;
# i realised that some customer(s) visited twice or more in a single Day !!
## this means to find count of days i have to use distinct on order_date so that
# duplicates are eliminated and i get the right Day Count .
# to find the count of days i must use count() function.
# i realised that there are multiple enteries for the same customer that means i have to
# group the data by customer_id to find the right count.
# Here are the Steps
# TO Determine the unique nunmber of visits for each customer utlize count(distinct
order_date))
# its important to apply the distinct keyword while caclucating the visit count to avoid duplicate
# counting of days
-- here is the solution
select customer_id ,
count(distinct order_date) as 'visit_Count'
from sales
group by customer_id;
select order_date from sales;
-- Ranking + Partitioning + CTE
-- Karry Wants to Know
-- What was the First Item from the Menu Purchased by Each Customer ?
-- which table provides purchase Details ? Sales
-- Which Table Provides Product Details ? Menu
select * from sales;
# if i want First Item from the Menu i realised i must sort the Date by
# order_date from sales in ascending Order.
# i realised if i use dense_rank() over order_date ascending order i ll get Rank 1 for the First
# Order.
select *, dense_rank() over (order by order_date) as prank
from sales;
-- i realised that rank is not reseting or regenerating when customer_id is changing?
-- i realised that i must partition data by customer_id to see the effective ranks.
-- i fill use Common Table Expression to filter the data where ProductRank matches with 1
-- to find the First Order Placed by Customer.
# here are the steps
# 1. Create a common Table Expression(CTE) named ordered_sales_cte.
# within CTE , create a new column 'ord_rank' and caluclate the
# row number using dense_rank() window function.
# the partition by clause divides the data by customer_id, and the
# order by clause orders teh rows within each partion by order_date
# 2. in the outer query , select the appropriate columns and apply a filter in the where clause
# to retrieve only the rows where the ord_rank column = 1 which represents the first row wihin
each
# customer_id partition.
# 3. use the gorup by clause to group the result by customer_id and product_name;
# expected answer
# Customer_ID | Product_Name
# here is the solution
select
s.customer_id,
s.order_date,
m.product_name ,
dense_rank() over ( partition by s.customer_id order by s.order_date ) 'ord_rank'
from sales s inner join menu m
on
s.product_id = m.product_id;
with ordered_sales as (
select
s.customer_id,
s.order_date,
m.product_name ,
dense_rank() over ( partition by s.customer_id order by s.order_date ) 'ord_rank'
from sales s inner join menu m
on
s.product_id = m.product_id
) select customer_id, product_name ,ord_rank from ordered_sales where ord_rank=1
group by customer_id, product_name;
# Karry Wants to KNOW
#
========================================================================
=====================
# What is the Most Purchased Item on the Menu and how many times was it purchased by All
Customers ?
# Purchase Data reference SALES
# Name of Product Table Reference: MENU
# Expected Output :
# Purchase_Count | ProductName
# Observations
# because the data is splited into 2 tables sales & menu u must use join here to merge table
# Fetch ProductIds from Sales and ProductNames from Menu
# group records by ProductNames and find count of(ProductIds) as purchaseCount
# sort data by purchaseCount desc order and fetch first row using limit .
select
count(s.product_id) as most_purchased_item,
m.product_name
from sales s inner join menu m
on
s.product_id = m.product_id group by m.product_name
order by most_purchased_item desc limit 1;
-- it is Simple query language..
# karry Wants to KNow
# Which item was the Most Popular for Each Customer ?
# ranking+ partitioning+ joins
# Here are the steps
# 1. Create a CTE named fav_item_cte and within CTE, join the menu table and sales table
using
# product_id column
# 2. Group results by sales.customer_id and menu.product_name and claculate the count of
menu.product_id
# occurences for each group.
# 3. Utilize the dense_rank() window function to caluclate the ranking of each sales.customer+id
partition
# based on the countof orders count(sales.customer_id) in descending order
#4. in the outer quer , select the appropirate columns and apply a filter in the where clause to
retreive only
# the rows where the rnak column equals 1, representing the rows from the highest order count
# for each customer
# expected output:
# cutsomer_id | product_name | order_count
#A Ramen 3
#B Sushi 2
with fav_item_cte as
(
select
s.customer_id,
m.product_name,
count(m.product_id) as order_count,
dense_rank() over (
partition by s.customer_id order by count(s.customer_id) desc) as 'order_rank'
from menu m inner join sales s
on
m.product_id = s.product_id
group by s.customer_id,m.product_name
) select customer_id,product_name,order_count from fav_item_cte where order_rank=1;
create table stockprices(
dates date , price int);
insert stockprices
values
('2023-10-01',10.0),
('2023-10-02',11.0),
('2023-10-03',12.0),
('2023-10-04',13.0),
('2023-10-05',14.0);
select * from stockprices;
## karry wants to know the simple Moving Average(SMA) over last 3 Days.
select dates,
price,
avg(price) over(order by dates rows between 2 preceding and current row) as ThreeDaySMA
from stockPrices;