Group by inside inner join 1055 - mysql

So, i have 2 tables one of them is a control list of holidays (1 for holiday and 0 for not holiday) and the day of the week on that date it kinda looks like this:
calendar_date
Day_of_week
Holiday_flg
2016-01-02
Monday
1
2016-02-03
Friday
0
2016-02-01
Monday
1
And a second table with some restaurant info that looks like this:
Visit date: refers to the day the visitors arrive at the restaurant
Reserve visitors: refers to the day the visitors created a reservation on the restaurant (not used in this problem, just part of the main table)
ID
Visit_date
reserve_datetime
reserve_visitors
1023044
2016-02-01
2016-01-01
5
1041331
2016-01-01
2016-01-01
2
1023044
2016-01-01
2016-01-01
4
I used this query to join both tables together by date
SELECT * from restaurants_visitors
inner join date_info
on restaurants_visitors.visit_date= date_info.calendar_date
where holiday_flg=1
limit 10
;
which returns both tables joined by the date
I want to group them by restaurant ID, so i can get the highest average number of vistors on holidays, and the percentage of growth of the amount of visitors week over week for the last 4 weeks
So far i have tried something like this
SELECT * FROM restaurants_visitors as rv
inner join date_info as df
on rv.visit_date= df.calendar_date
where df.holiday_flg=1
group by rv.id
limit 10
;
But i keep getting this error code:
Error Code: 1055. Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'database.restaurants_visitors.visit_date' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by 0.024 sec
Expected Output
List of top 5 more visited restaurants in holidays( Table with id of restaurant and avg visitors on holidays)in dsc order
ID
Average_visitorsin_holidays
1023044
4.5
1041331
2
List of percentage of growth of the amount of visitors week over week for the last four weeks of the data?(Table with percentage of growth over weeks)
week
percentage of growth over last week
4
unknow result
3
unknow result
Which day of the week there are usually more visitors on average in restaurants.
(single row with day of the week with more visitors)
Day of the week
AVG visitor per day of week
Monday
4.5
1041331
1

Ok, the main problem is that you're selecting ALL the columns but only defining rv.id as the group identifier.
You want to start with something like this:
SELECT
rv.id,
df.calendar_date,
sum(rv.reserve_visitors) as total_visitors
FROM
restaurants_visitors as rv
inner join
date_info as df on rv.visit_date= df.calendar_date
WHERE
df.holiday_flg=1
GROUP BY
rv.id,
df.calendar_date
This will tell you the total visitors per restaurant per holiday. With that in hand, we can find the average visitors per restaurant on holidays:
WITH
holiday_visitors as (
SELECT
rv.id,
df.calendar_date,
sum(rv.reserve_visitors) as total_visitors
FROM
restaurants_visitors as rv
inner join
date_info as df on rv.visit_date= df.calendar_date
WHERE
df.holiday_flg=1
GROUP BY
rv.id,
df.calendar_date
)
SELECT
id,
avg(total_visitors) as avg_holiday_visitors
FROM
holiday_visitors
GROUP BY
id
ORDER BY
avg_holiday_visitors desc
This will tell you which restaurants had the most traffic on average on holidays. How you limit it to the top 5 depends on the database you are using.

Related

I would like to count the number of users who made multiple purchases grouped by month

So what i'm trying to do here, is that i am trying to count the number of repeat users (users who made more than one order) in a period of time, let it be month day or year, the case here is months
i'm currently running mysql mariadb and i'm pretty much a beginner in mysql, i've tried multiple subqueries but all have failed till now
This is what i have tried so far ..
This returns all the number of users with no ordering count condition
Since people are asking for sample data, here is what the data is looking like at the moment:
Order_Creation_Date - User_ID - Order_ID
2019-01-01 123 1
2019-01-01 123 2
2019-01-01 231 3
2019-01-01 231 4
This is the query i am using to get the result but it keeps on returning total number of users within the month
select month(o.created_at)month,
year(o.created_at)year,
count(distinct o.user_uuid) from orders o
group by month(o.created_at)
having count(*)>1
and this returns the number of users as 1 ..
select month(o.created_at)month,
year(o.created_at)year,
(select count(distinct ord.user_uuid) from orders ord
where ord.user_uuid = o.user_uuid
group by ord.user_uuid
having count(*)>1) from orders o
group by month(o.created_at)
Expected result will be from the sample data above
Month Count of repeat users
1 2
If you want the number of users that make more than one purchase in January, then do two levels of aggregations: one by user and month and the other by month:
select yyyy, mm, sum( num_orders > 1) as num_repeat_users
from (select year(o.created) as yyyy, month(o.created) as mm,
o.user_uuid, count(*) as num_orders
from orders o
group by yyyy, mm, o.user_uuid
) o
group by yyyy, mm;
I think you should try something like this which will return USer_ID list Month and Year wise who ordered more that once for the period-
SELECT
[user_uuid],
MONTH(o.created_at) month,
YEAR(o.created_at) year,
COUNT(o.user_uuid)
FROM orders o
GROUP BY
MONTH(o.created_at),YEAR(o.created_at)
HAVING COUNT(*) > 1;
For more, if you are looking for the count that how many users placed more that one order, you can just place the above query as a sub query and make a count on column 'user_uuid'

How get earnings per month MYSQL Query

I have two tables, one table called "tbl_materiales", and another called "tbl_pedidos".. In the table called tbl_materiales" I have information about all my products, Like Description, and the most important "Price"...
In my table "tbl_pedidos", i register all information of products that the user register in the website.
For example:
tbl_materiales:
IdProduct Description Price
5 Product one 8
6 Product three 10
7 Product four 15
tbl_pedidos
IdProduct Quantity Month
5 10 January
6 5 January
7 2 February
So, I want to know all the earnings PER month...
I want to have this: The column earnings is the multiplication of tbl_pedidos.Quantity * tbl_materiales.Price, obviously it depends of the price of the product, and the quantity sold out.
Month Earnings
January 130
February 30
Now, I have this, but it doesn't bring me the correct information...
SELECT tbl_pedidos.Mes
, (SUM(tbl_pedidos.Cantidad) * tbl_materiales.Precio) as Total
FROM tbl_pedidos
INNER JOIN tbl_materiales
ON tbl_pedidos.IdMaterial = tbl_materiales.IdMaterial
GROUP BY tbl_pedidos.Mes
ORDER BY tbl_pedidos.Fecha;
SELECT tbl_pedidos.Mes , SUM(tbl_pedidos.Cantidad*tbl_materiales.Precio) as Total
FROM tbl_pedidos
INNER JOIN tbl_materiales
ON tbl_pedidos.IdMaterial = tbl_materiales.IdMaterial
GROUP BY tbl_pedidos.Mes
ORDER BY tbl_pedidos.Fecha;
Check http://sqlfiddle.com/#!9/de665b/1
The query can be like :
SELECT tbl_p.Month
,sum(as tbl_m.Price*TP.Quantity) AS Earnings
FROM tbl_materiales AS tbl_m
JOIN tbl_pedidos AS tbl_p
ON tbl_m.IdProduct = tbl_p.IdProduct
GROUP
BY tbl_p.Month;
In this case I have used Where instead of Join, maybe de next sentence resolve your problem:
select TP.Month,sum(TM.Price*TP.Quantity) as Earnings
from TBL_Pedidos TBP,TBL_Materiales TM
where TP.IdProduct = TM.Id_Product
group by TP.Month
Group by is the solution

how to write a Query in Mysql

I have 2 tables.ms_expese and track_expense.Using this table generate a fact table
I want the expense_name in ms_expense,expense_amount from track_expense.
I want to get the sum of expense_amount for a particular expense_name based on date.The date in the order of 1,2...12 as month id
SELECT DATE_Format(a.date,'%b') as month_id,b.expense_name AS expense_type, sum(a.expense_amount) AS expense_amount FROM ms_expense b JOIN track_expense a on a.`expense_id`=b.`expense_id` group by DATE_Format(a.date,'%b')
how to put the month id in the order of 1,2,..12 and my date format y-m-d
I get the month in apr,aug and so on but i need jan as 1,feb as 2
I have 25 expenses(expense name).In this query i got the total expense amount of first expense only.I want the total expense of all expenses in every month
CREATE TABLE fact AS
(<your select query>)
Your select query can be in the following form
SELECT MONTH(date)as month_id,expense_name,sum(expense_amount)
FROM ms_expense JOIN track_expense using (expense_id)
group by expense_name,MONTH(date)

SQL sales report by calendar week

I've been Googling for a few hours... thought this would be easy, but clearly not for me :)
I've got sales data in two tables and I want to generate a weekly sales report for a specific item. For this purpose, I don't care about dollar values, just number of units. An a "week" is either a calendar week (whatever start day, I don't care) or just 7-day chunks back from current (so week 1 is the last 7 days, week 2 is 8 - 15 days ago, etc) - whichever is easier. I'm simply trying to monitor sales trends over time. Preferably it would span back over years so that if its the first week of January, for example, it wouldn't show just one record.
The data comes from ZenCart. The relevant tables/column structure is here:
Table "orders" has columns: orders_id, date_purchased
Table "orders_products" has columns: orders_id, products_id, product_quantity
Where I'm having trouble is with the joins and syntax.
This worked for my needs:
SELECT o.date_purchased, CONCAT(YEAR(o.date_purchased), LPAD(WEEK(o.date_purchased), 2, '0')) as weekyear, op.products_id, SUM( op.products_quantity )
FROM orders_products op
LEFT JOIN orders o ON op.orders_id = o.orders_id
WHERE op.products_id = 331
GROUP BY weekyear
ORDER BY weekyear
If you have some date/datetime/timestamp column, you can use the week function in your where clause
select week(now()) as week, sum(units) as total
from sales
where week(sales_date) = week(now());
or the previous week
select week(now()) - 1 as week, sum(units) as total
from sales
where week(sales_date) = week(now()) - 1;
You must take care for the year wrap around from week 52/53 to week 0/1.
SQLFiddle for testing.
In order to take care of the year end wrap. for instance, week(12/30/2018)=52 and week(12/31/2018)=52 both are considered week 52 of 2018. the first day of 2019 starts on a Tuesday. you can write a case statement as follows to move 12/30/2018 and 12/31/2018 to the first week of 2019. so that you will have a complete 7 days week to compare:
case when order_date in ( '2018-12-30', '2018-12-31')
then 0
else week(order_date)
end as order_week

How to count and group items by day of the week?

I have the following (MySQL) table called "tweets":
tweet_id created_at
---------------------
1 1298027046
2 1298027100
5 1298477008
I want MySQL returning the number of tweets per day of the week; taking the above data it should return:
Wednesday 1
Friday 2
I now have the following query (which should return the day of the week index, not the full name):
SELECT
COUNT(`tweet_id`),
WEEKDAY(FROM_UNIXTIME(`created_at`))
FROM tweets2
ORDER BY WEEKDAY(FROM_UNIXTIME(`created_at`))
This however returns:
COUNT(`tweet_id`) WEEKDAY(FROM_UNIXTIME(`created_at`))
7377 4
(There are a total of 7377 tweets in the database). What am I doing wrong?
SELECT
COUNT(`tweet_id`),
DAYNAME(FROM_UNIXTIME(created_at)) AS Day_Name1
FROM tweets2
GROUP BY Day_Name1
ORDER BY Day_Name1;
You have a count, but you don't have a group by. You should include a
GROUP BY WEEKDAY(FROM_UNIXTIME(`created_at`))
You are not grouping by week day so you only get one grand total. Try this:
SELECT
COUNT(`tweet_id`),
WEEKDAY(FROM_UNIXTIME(`created_at`))
FROM tweets2
GROUP BY WEEKDAY(FROM_UNIXTIME(`created_at`))
ORDER BY WEEKDAY(FROM_UNIXTIME(`created_at`));