Query to create new fields based on the time span - mysql

I am unable to write a query which needs the following :
I have 4 tables of Game products:
Table 1 (Soccer)
Product_Name
SoccerBall
SoccerShoes
SoccerShins
Table2 (Cricket)
Product_Name
CricketBall
CricketStumps
CricketBat
Table3(Rugby)
Product_Name
RugbyBall
Table4(Pingpong)
Product_Name
Pingpongball
I also have a table generating a revenue about all the products which is as follows:
Table5
Userid OrderSno Product_Name OrderTime Revenue
123 66243 CricketBall 12Jan2012 35
123 66553 CricketBat 15June2013 60
123 36476 SoccerBall 15Dec2013 15
The result table should be something like this :
Ordertime(Sorted) Cricket(3months) Cricket(6months) Cricket(Lifetime)
12Jan2012 0 0 0
15June2013 0 0 35
15 Dec2013 0 60 95 (60+35)
Soccer(3 months) Soccer(6months) Soccer(Lifetime)
0 0 0
0 0 0
0 0 0
The above table gives the revenue generated for every product purchased before that particular product was purchased. This is based on the orderdate/time sorted.
For example : The first order placed by user 123 was on 12Jan2012. So that user had not purchased anything before that since it was his first order. Hence the first row of the result table should be 0.
Coming to the 2nd row, the 2nd purchase that he made was on 15June2013. SO the result table should contain all the revenue for the respective product type before 2nd order was made. Hence in this case 35 would be there under Cricket field (Since the Product_name belongs to Cricket table) and it would fall into the Lifetime field. This is because the order purchase date is 15June2013. So 3 months before this nothing was purchased. Similarly 6 months before this date nothing was purchased. But before 1 year or more than that Cricket Ball was purchased which generated a revenue of 35. Hence the value of 35 should fall into Lifetime field of Cricket based on the Product_Name of Cricket Ball.
The same thing should happen for all the products. I know the query is complex and i am not sure whether this is feasible or not. Since i am new to any help regarding this would be appreciated.

Well I am not sure if this exactly what you want but I think its work taking a look at. If you want all the sport in one table a Union would do it.
Select Product_Name
,YEAR(ordertime)
,SUM(case when MONTH(ordertime) in (1,2,3) then revenue else 0 end) 'Q1'
,SUM(case when MONTH(ordertime) between 1 and 6 then revenue else 0 end) 'Q2'
,SUM(case when MONTH(ordertime) between 1 and 9 then revenue else 0 end) 'Q3'
,SUM(revenue) 'Q4'
from PingPong
group by Product_Name, YEAR(ordertime)

Related

SQL query for getting count of certain columns for every day across a date range

I have an 'actions' table in the following format:
id
action
category_id
created_date
1
fff
3
12/11/2020
2
aaa
7
12/04/2021
3
bbb
3
04/01/2016
which is in a one-to-many relationship with 'categories' table (one category can have many actions, category_id is the foreign key above) in the following format:
id
name
1
Cat-1
2
Cat-2
I need an API that receives a date range (start and end values) as an input an should return the total number of actions for all categories that take place for every day within that range, like so:
day
Cat-1
Cat-2
10/1/2020
22
56
06/8/2011
56
78
Basically showing how many actions of a particular category took place per day in that date range.
My initial way of solving this was to fetch the data grouped by date and then manipulate that in the code. But I want to know if there's a way to do achieve this with SQL itself.
select created_date as day
,count(case when name = 'Cat-1'then 1 end) as 'Cat-1'
,count(case when name = 'Cat-2'then 1 end) as 'Cat-2'
from t join t2 using(id)
group by created_date
day
Cat-1
Cat-2
2020-12-11
1
0
2021-12-04
0
1
Fiddle

Mysql count rows of distinct values of price between range from give ids and return sum of count values

Hi I have two tables one is product and next is price table
Product Table
Id Name
1 Bike
2 Car
3 Van
Price Table
Id Price Pid
1 100 1
2 150 1
3 200 1
4 100 2
5 110 2
6 120 2
7 300 3
8 310 3
My Sql query
$sql = "SELECT SUM(CASE WHEN price >= 0 AND price <= 200 THEN 1 ELSE 0 END) AS `0-2`,
SUM(CASE WHEN price >= 201 AND price <= 500 THEN 1 ELSE 0 END) AS `2-5`,
COUNT(pid) AS `All Values`
FROM price where pid IN(1,2,3)";
when I run this query price count values showing like below
0-2 has (6) count
2-5 has (2) count
but here I need to display as like.
here I am looking to display as two products between 0-200 matched that are 1,2 pids and so on
0-2 (2) count
2-5 (1) count
because in price table there are more price options there for products so every product has 2 to 5 different prices in the table but I should display it as one product count even more prices had.
Kindly tell me how to write mysql query.
I would appreciate you help.
You can use COUNT(DISTINCT CASE ..) and in THEN clause use pid instead of 1
SELECT
COUNT(DISTINCT CASE WHEN price >= 0 AND price <= 200 THEN pid END) AS `0-2`,
COUNT(DISTINCT CASE WHEN price >= 201 AND price <= 500 THEN pid END) AS `2-5`,
COUNT(DISTINCT pid) AS `All Values`
FROM price
WHERE pid IN(1,2,3)
DEMO

mysql sorting data in two levels possible?

Iam trying to analyze some date from a mysql table.
The data is a representation of incomming calls, each line represents one call
category purpose
cars question
bikes question
cars question
cars complaints
scooters question
bikes complaints
now for the plotting I need the data to look like this
category cat_count question complaints
cars 3 2 1
bikes 2 1 1
scooters 1 1
I figured out that I can sort and count by one field by using something like this
SELECT category, count(*) FROM stat GROUP BY category ORDER BY count(*) desc;
which will give me
category count
cars 3
bikes 2
scooters 1
but how can I add the purpose counts to that output?
I would usually write a php or bash script, but if its possible to do it in mysql I would rather do it like that instead of having a 3 loop script noone will understand in 1 year :-))
Thanks in advance for any hint (even if the hint is "impossible")
You can do this way:
SELECT category, count(*) as cat_count,
SUM(CASE WHEN purpose='question' THEN 1 ELSE 0 END) as question,
SUM(CASE WHEN purpose='complaints' THEN 1 ELSE 0 END) as complaints
FROM stat
GROUP BY category
ORDER BY count(*) desc;
Result:
CATEGORY CAT_COUNT QUESTION COMPLAINTS
cars 3 2 1
bikes 2 1 1
scooters 1 1 0
See result in SQL Fiddle.

Insert into MYSQL table last submission date for a review

I have a table called 'ratings' which contains an index which is a unique ascending number, ProductId which is a product code, rate1 to rate5 are the number of times each product has recieved a 1 or 5 star rating by a customer aveRate is the average rating for each product and lastSubDate should be the timestamp of when the last review for each product was submitted but it's currently empty.
id ProductId rate1 rate2 rate3 rate4 rate5 aveRate lastSubDate
18 9996637 0 0 0 0 1 5 0000-00-00 00:00:00
26 9996628 1 0 0 0 0 1 0000-00-00 00:00:00
34 9996618 0 0 0 1 0 4 0000-00-00 00:00:00
36 9996614 5 0 0 0 0 1 0000-00-00 00:00:00
48 9996592 5 0 1 0 3 3 0000-00-00 00:00:00
66 9996566 0 0 0 1 3 5 0000-00-00 00:00:00
In another table I have called 'last_rate_date' I have ProductId and the date the product was last rated under lastSubDate. In this table the Product Id's can appear several times as per the example as each row represents a time a review was submitted by a customer.
ProductId lastSubDate
9996665 2009-05-22 19:45:05
9996665 2009-08-06 11:30:07
9996665 2010-11-10 08:30:17
9996665 2011-06-10 09:15:47
9996665 2011-06-12 05:15:39
My questions is how can I modify the first table 'ratings' using SQL to insert the last time a product was reviewed under the 'lastSubDate' using the second table 'last_rate_date' to lookup the productId and the date bearing in mind each ProductId may appear mutiple times in this seconds table with differen't dates.
This needs to be one as a one off table modification to the first table. Adter this is done I will amend the script which adds data to ratings table to always add a timestamp in the future when it's updated.
You can get most recent dates for each "ProductId" using the query below:
Select ProductId, MAX(lastSubDate)
From last_rate_date
Group By ProductId
This will produce each ProductId that appears in the second table, along with the latest date (using the MAX function). The Group By clause is needed to define what the aggregation is run against.
To further solve your problem, you can insert this Select statement into an Update statement like so:
UPDATE ratings a
INNER JOIN (
Select ProductId, MAX(lastSubDate) as finalLastSubDate
From last_rate_date
Group By ProductId ) b
ON a.ProductId = b.ProductId
SET a.lastSubDate = b.finalLastSubDate
You can use the timestamp with CURRENT_TIMESTAMP default
or you can add the date on the insert.
$date = date ("m-Y-d, H: i: s")

Select with a where clause and without it in the same query

I'm trying to find a way to sum amounts that match a specific term, and also amounts that don't match it. For example, if my table looks like this
user amount description
1 34 bike
1 78 toys
2 3 fuel
2 12 bike
I'm trying to get a table that will look like this in the end:
user amount spent on bike amount spent total
1 34 112
2 12 15
I'm using mysql
You can use a CASE statement within a SUM grouping:
SELECT user,
SUM(CASE WHEN description = 'bike' THEN amount ELSE 0 END) bike_amount,
SUM(amount) total_amount
FROM mytable
GROUP BY user