How do i find the most frequent facility in SQL - sql

Currently, my table comprises two - Facility table Facility table and Booking table Booking table
How do I list the most used popular facility used by the members in 2017?
Year has to be 2017
The most frequent facility used each month
After trying to do
This is what I have now
SELECT
MONTH(b.BookingStartDateTime) AS 'Month',
f.FacilityDesc AS 'MOST FREQUENT'
FROM
Booking b
INNER JOIN
Facility f ON b.FacilityID = f.FacilityID
WHERE
YEAR(b.BookingStartDateTime) = 2017
GROUP BY
MONTH(b.BookingStartDateTime), f.FacilityDesc
ORDER BY
MONTH(b.BookingStartDateTime) DESC

I believe this should work.
select Month, 'Most Frequent' from (
select *, row_number() over (partition by Month order by Frequency desc) rnk from (
SELECT
MONTH(b.BookingStartDateTime) AS 'Month',
f.FacilityDesc AS 'MOST FREQUENT',
count(*) as 'Frequency'
FROM
Booking b
INNER JOIN
Facility f ON b.FacilityID = f.FacilityID
WHERE
YEAR(b.BookingStartDateTime) = 2017
GROUP BY
MONTH(b.BookingStartDateTime), f.FacilityDesc
) rnk
) a where rnk = 1
order by month desc
Added a non-window function version, you need to do inner joins or where exists method to get your result
with rnk as (
SELECT
MONTH(b.BookingStartDateTime) AS 'Month',
f.FacilityDesc AS 'MOST FREQUENT',
count(*) as 'Frequency'
FROM
Booking b
INNER JOIN
Facility f ON b.FacilityID = f.FacilityID
WHERE
YEAR(b.BookingStartDateTime) = 2017
GROUP BY
MONTH(b.BookingStartDateTime), f.FacilityDesc
)
select Month, 'Most Frequent' from rnk where exists(
select Month, freq from (
select Month, max(Frequency) freq from rnk group by Month
) a where a.Month = rnk.Month and a.freq = rnk.Frequency
)
order by Month desc

Related

Joining two queries together into one main table

I have the following two queries that I need to join together to get one final output.
The primary keys are year, month,cost_center, g.account, and e.submapping.
The first table is an acutals table from a GL while the second query is a planned amount. I am trying to compare actuals to plan and need to join these two tables with the primary keys listed.
---Query 1 (e)
with Ranking as (
select c.*, rank() over(partition by
c.ledger_name,
c.company_code,
c.location_code,
c.cost_center,
c.account_number,
c.period_name,
c.currency,
c.amount,
c.entered_amount,
c.dm_insert_dt
order by dw_last_updated DESC) rnk
from wbr_global.gl_ap_details c
where cost_center IN ('1168','1153','1172','1257')
and ledger_name IN ('ABC.com, Inc.')
and account_number between '59999' and '70000')
select
to_date(period_name, 'Mon-YY') as BalanceDate,
date_part(month,(to_date(period_name, 'Mon-YY'))) as Months,
Case
when right(period_name,2) = right(date_part_year(current_date),2) then 'Current Year'
when right(period_name,2) = right(date_part_year(current_date) - 1,2) then 'Prior Year'
else 'Error' end as YearFlag,
EXTRACT(YEAR from balancedate) as year,
EXTRACT(Month from balancedate) as month,
e.sub_mapping,
c.cost_center,
c.period_name,
sum(c.amount) as amount
from Ranking c
left join wbr_global.raw_station_extended_attribute d on c.location_code = d.location_code
left join sandbox.utr_fixed_mapping_na e on c.account_number = e.account_number
where c.cost_center IN ('1168','1153','1172','1257')
and c.ledger_name = 'abc.com, Inc.'
and c.rnk = 1
group by 1,2,3,4,5,6,7,8
limit 10
Here is the second query
---Second query g
EXTRACT(YEAR from first_day_of_month) as year,
EXTRACT(Month from first_day_of_month) as month,
first_day_of_month,country,cost_center,scenario,'employee_relation' as account,
sum(employee_relation) as amount
from prophecy_to_sabre_ds_db.prophecy_caffeine.output_ww_field_opex
where cost_center = 1172
AND scenario = 'Q2G_22_1'
group by 1,2,3,4,5,6
Would I be able to make one a sub query in the other and join that way.
(Query 2) as g on g.cost_center = c.cost_center
and g.account = e.sub_mapping
and g.year = e.year
and g.month = e.month

Create a column with daily count in impala

I want to create a count column which will has the count per day. I have managed to do it like this:
select book, orders, s.common_id,s.order_date,d.customer_region,t.cnt
from books_tbt as s
inner join customer_tbt as d
on s.common_id = d.common_id
inner join (select count(*) as cnt,order_date from customer_tbt where customer !='null'
group by order_date) as t
on t.order_date = d.order_date
where d.customer !='null'
and s.order_date = 20220122
group by book, orders, s.common_id,s.order_date,d.customer_region,t.cnt;
I want to ask if there is a more efficient way to do it?
You can simply use COUNT(*) OVER( Partitioned by ORDER_DATE Order by ORDER_DATE) window function to calculate count for an order date.
select book, orders, s.common_id,s.order_date,d.customer_region,d.cnt
from books_tbt as s
inner join
( select d.*, COUNT(*) OVER( Partition by ORDER_DATE Order by ORDER_DATE) as cnt from customer_tbt d) as d on s.common_id = d.common_id -- count(*) over can not be calculated together with group by so we are using a sub qry
where d.customer !='null'
and s.order_date = 20220122
group by book, orders, s.common_id,s.order_date,d.customer_region,d.cnt;

SQL get top 3 values / bottom 3 values with group by and sum

I am working on a restaurant management system. There I have two tables
order_details(orderId,dishId,createdAt)
dishes(id,name,imageUrl)
My customer wants to see a report top 3 selling items / least selling 3 items by the month
For the moment I did something like this
SELECT
*
FROM
(SELECT
SUM(qty) AS qty,
order_details.dishId,
MONTHNAME(order_details.createdAt) AS mon,
dishes.name,
dishes.imageUrl
FROM
rms.order_details
INNER JOIN dishes ON order_details.dishId = dishes.id
GROUP BY order_details.dishId , MONTHNAME(order_details.createdAt)) t
ORDER BY t.qty
This gives me all the dishes sold count order by qty.
I have to manually filter max 3 records and reject the rest. There should be a SQL way of doing this. How do I do this in SQL?
You would use row_number() for this purpose. You don't specify the database you are using, so I am guessing at the appropriate date functions. I also assume that you mean a month within a year, so you need to take the year into account as well:
SELECT ym.*
FROM (SELECT YEAR(od.CreatedAt) as yyyy,
MONTH(od.createdAt) as mm,
SUM(qty) AS qty,
od.dishId, d.name, d.imageUrl,
ROW_NUMBER() OVER (PARTITION BY YEAR(od.CreatedAt), MONTH(od.createdAt) ORDER BY SUM(qty) DESC) as seqnum_desc,
ROW_NUMBER() OVER (PARTITION BY YEAR(od.CreatedAt), MONTH(od.createdAt) ORDER BY SUM(qty) DESC) as seqnum_asc
FROM rms.order_details od INNER JOIN
dishes d
ON od.dishId = d.id
GROUP BY YEAR(od.CreatedAt), MONTH(od.CreatedAt), od.dishId
) ym
WHERE seqnum_asc <= 3 OR
seqnum_desc <= 3;
Using the above info i used i combination of group by, order by and limit
as shown below. I hope this is what you are looking for
SELECT
t.qty,
t.dishId,
t.month,
d.name,
d.mageUrl
from
(
SELECT
od.dishId,
count(od.dishId) AS 'qty',
date_format(od.createdAt,'%Y-%m') as 'month'
FROM
rms.order_details od
group by date_format(od.createdAt,'%Y-%m'),od.dishId
order by qty desc
limit 3) t
join rms.dishes d on (t.dishId = d.id)

Compose a SQL query that produces monthly revenue by channel and the previous month's revenue

Hey everyone I have two tables with output like this:
Month_Table
Transaction_Table
I need to calculate the monthly revenue by channel and the previous month's revenue: I did this query but it is not completed
Select date_created, channel, sum(revenue) as monthly_revenue
from transaction_table
GROUP BY date_created,channel
The result should be displaying monthly revenue and the month's revenue of previous month.
How can I do that?
try this code .
with resultTable as(
select RT.channel,RT.sumRevenue,LT.[month-start_date],LT.month_end_date,LT.year_month
from (select t.channel,sum(revenue) as sumRevenue,M.month_index from Month_Table M,Transaction_Table T
where t.date_created BETWEEN m.[month-start_date] AND m.month_end_date
group by m.month_index,t.channel) RT Join Month_Table LT on RT.month_index = LT.month_index
)
select * from resultTable
output:
OR use this query
with resultTable as(
select RT.channel,RT.sumRevenue,LT.[month-start_date],LT.month_end_date,LT.year_month
from (select t.channel,sum(revenue) as sumRevenue,M.month_index from Month_Table M,Transaction_Table T
where t.date_created BETWEEN m.[month-start_date] AND m.month_end_date
group by m.month_index,t.channel) RT Join Month_Table LT on RT.month_index = LT.month_index
)
select *,LAG(sumRevenue,1) OVER (PARTITION BY channel ORDER BY channel) previous_month_sales from resultTable
output:
You could try uing a a join between you tables
Select a.month_index, a.year_month, b.channel, sum(b.revenue) as monthly_revenue
from Month_Table a
from transaction_table b ON b.date_created between a.month_start_date and a.month_and_date
amd month(b.date_created) = betwwen month(curdate()) -1 and month(curdate())
GROUP BY a.month_index, a.year_month, b.channel
order by a.year_month desc
Try this:
Select t1.date_created, t1.channel, sum(t1.revenue) as monthly_revenue ,sum(t2.revenue) prev_month_revenue
from transaction_table t1 left join transaction_table t2 on t1.channel = t2.channel and to_char(t1.date_created,'MM') = to_char(add_months(t2.date_created,-1),'MM')
GROUP BY t1.date_created,t1.channel;

How to return the most ordered item for each month

I am trying to return the most ordered product per month, of the year 2007. I would like to see the name of the product, how many of them where ordered that month, and the month. I am using the AdventureWorks2012 database. I have tried a few different ways but each time multiple product orders are returned for the same month, instead of the one product that had the most order quantity that month. Sorry if this is not clear. I am trying to test myself so I make up my own questions and try to answer them. If anyone knows a site that have questions and answers like this so I can verify that would be super helpful! Thanks for any help. Here is the farthest I have been able to get with the query.
WITH Ord2007Sum
AS (SELECT sum(od.orderqty) AS sorder,
od.productid,
oh.orderdate,
od.SalesOrderID
FROM Sales.SalesOrderDetail AS od
INNER JOIN
sales.SalesOrderHeader AS oh
ON od.SalesOrderID = oh.SalesOrderID
WHERE year(oh.OrderDate) = 2007
GROUP BY ProductID, oh.OrderDate, od.SalesOrderID)
SELECT max(sorder),
s.productid,
month(h.orderdate) AS morder --, s.salesorderid
FROM Ord2007Sum AS s
INNER JOIN
sales.SalesOrderheader AS h
ON s.OrderDate = h.OrderDate
GROUP BY s.ProductID, month(h.orderdate)
ORDER BY morder;
Make a CTE that groups our products by month and creates a sum
;WITH OrderRows AS
(
SELECT
od.ProductId,
MONTH(oh.OrderDate) SalesMonth,
SUM(od.orderqty) OVER (PARTITION BY od.ProductId, MONTH(oh.OrderDate) ORDER BY oh.OrderDate) ProdMonthSum
FROM SalesOrderDetail AS od
INNER JOIN SalesOrderHeader AS oh
ON od.SalesOrderID = oh.SalesOrderID
WHERE year(oh.OrderDate) = 2007
),
Make a simple numbers table to break out each month of the year
Months AS
(
SELECT 1 AS MonthNum UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8
UNION SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12
)
We query our months table against the data and select the top product for each month based on the sum
SELECT
m.MonthNum,
d.ProductID,
d.ProdMonthSum
FROM Months m
OUTER APPLY
(
SELECT TOP 1 r.ProductID, r.ProdMonthSum
FROM OrderRows r
WHERE r.SalesMonth = m.MonthNum
ORDER BY ProdMonthSum DESC
) d
Your group by statement should not include oh.OrderDate, od.SalesOrderID because this will aggregate your data to the incorrect level. You want the ProductID that was most commonly sold per month so the group by conditions become ProductID, datepart(mm,oh.OrderDate). As Andrew suggested the Row_Number function is useful in this case as it lets you create a key that is ordered by month and sorder and which resets each month. Finally in the outer query limits the results to the first instance (which is the highest quantity)for each month.
WITH Ord2007Sum
AS(
SELECT sum(od.orderqty) AS sorder,
od.productid,
datepart(mm,oh.OrderDate) AS 'Month'
row_number() over (partition by datepart(mm,oh.OrderDate)
Order by datepart(mm,oh.OrderDate)desc, sorder desc) row
FROM Sales.SalesOrderDetail AS od
INNER JOIN
sales.SalesOrderHeader AS oh
ON od.SalesOrderID = oh.SalesOrderID
WHERE datepart(yyyy,oh.OrderDate) = 2007
GROUP BY ProductID, datepart(mm,oh.OrderDate)
)
SELECT productid,
sorder,
[month]
FROM Ord2007Sum
WHERE row =1