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

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

Related

how can I write a query in mySQL which shows the average trips in a day?

I have a list of IDs and the detail of the trips they've taken. I want to see how many trips each ID takes in a day on average but I don't know how to write this query. The data I have in my table is something like this:
ID
Ride_id
Date
1
123
2022-3-4
1
124
2022-3-4
1
111
2021-2-8
2
584
2019-4-18
2
256
2019-4-18
2
805
2020-5-8
2
127
2020-5-8
2
457
2020-5-8
3
100
2021-4-7
3
101
2021-4-7
3
202
2021-5-17
3
741
2021-5-17
So basically, the average rides ID=1 takes is 1.5 and the average rides ID=2 takes is 2.5 and so on. I need a query to calculate and show the result like this:
ID
Average_of_daily_trips
1
1.5
2
2.5
3
2
My current query uses only one condition: WHERE ID in ()
First count the trips on each day for each id, then make the average over those counts.
select id, avg(trips)
from (select id, count(*) as trips
from trips
-- where id in(1,2,3)
group by id, date) t
group by id
If you need to, you can uncomment the where clause in the subquery to filter for particular ids ...

Calculating the Difference Between Two Values in the Same Column using group by in mysql

I have a table as shown below. I want to do a partition and then subtract the values in the same column and different rows to get the difference using group by.
id
type
name
amount
1
sale
sam
2
2
sale
sam
15
3
return
lilly
20
4
sale
lilly
25
5
return
sam
3
6
sale
anju
20
And Need to return:
name
amount
sam
14
lilly
5
anju
20
Your sample data is a little suspect but I think you basically need to apply a case expression to your sale type:
select name,
Sum(amount * case when type='return' then -1 else 1 end) Amount
from t
group by name;

Aggregating data percentage wise based on date related criteria from a table

I have legacy tables which tracks flight and had to extract data. We have three tables named booking, airlines and flighttype. Note this is a dummy samples
booking :
id
customer
request_date
airline
flightType
price
currency
1
1
11-20-2020 10:23
1
1
120
Eur
2
1
11-21-2020 10:24
1
2
110
CHF
3
2
11-01-2020 11:25
2
2
120
Eur
4
1
15-01-2020 10:23
1
1
100
Eur
5
1
11-01-2020 11:23
1
2
60
Eur
6
1
12-01-2020 10:23
1
3
35
Eur
airline :
id
airline
1
French
2
Swiss
type :
id
flightType
1
domestic
2
international
Now the data we are trying to figure out is number of bookings consecutively within x days (let say if two days it would mean how many bookings were made in 2 days) for various parameters like
airline
flightType
airline & flightype
currency
price total price
For example lets say I wish to see what is the percentage of customer who have made multiple bookings within x days across multiple airline I should be able to do so or if I want to see the total revenue of customers who have made multiple booking within x days or customers who have made multiple booking with different set of currencies with x days
I am trying to make self join to extract such data and then group it but I am always reaching a dead end
SELECT
t1.customer, t1.request_date, t1.airline, count(*)
FROM booking t1
JOIN booking t2
ON t1.customer= t2.customer
WHERE t2.request_date > t1.request_date and DATEDIFF(t2.request_date, t1.request_date) > 0 and DATEDIFF(t2.request_date, t1.request_date) <=2
GROUP BY t1.customer, t1.request_date
The problem I am facing is the date has time and it gives me wrong results. And I am not sure what is the right way to get %share of customers who make booking in such way like
% share of customers who book more than one flight / more than one type of flight within span of x days.
Sorry if the question is too vague or if this violates any rules.
By the way I am using mysql 5.5
I want to see the total revenue of customers who have made multiple booking within x days or customers who have made multiple booking with different set of currencies with x days
You can answer questions like this using window functions. For the first question, this looks like:
select count(distinct customer)
from (select b.*,
lag(request_date) over (partition by customer order by request_date) as prev_request_date
from booking b
) b
where request_date <= prev_request_date + interval <n> day;

SQL Sum not returning the correct data

An example of my Progress database, opdetail table
invoice invline article size qty
----------------------------------------
905155 1 Shoe 10 5
905155 2 Slipper 3 2
905155 2 Slipper 4 6
905155 2 Slipper 5 1
905156 1 Boot 10 1
905156 1 Boot 11 1
905157 1 Slipper 5 4
905157 2 Shoe 8 6
a simple SQL select statement, run from the OpenEdge editor returns just what I need, a list of invoices with their total quantities:-
SELECT invoice, sum(qty) FROM opdetail GROUP BY qty ORDER BY invoice ASC
905155 14
905156 2
905157 10
HOWEVER:-
When run from an ASP page via DSN I have to list both fields in the GROUP BY otherwise progress returns a GROUP BY error
SELECT invoice, sum(qty) FROM opdetail GROUP BY qty, invoice ORDER BY invoice ASC
905155 5
905155 9
905156 2
905157 4
905157 6
Its not summarizing the qty, and seems to be taking into account the line number even though the line number plays no part in my sql statement. Can anyone throw any light on this or how I can do a sum of the total qty taking into account the line number? Thanks!
You are using qty in the aggregate function and then using on the group by this makes no sense and you should group by on some other column something as
SELECT
invoice,
sum(qty) FROM opdetail
GROUP BY invoice ORDER BY invoice ASC

Group data by age, gender and report requested in MySQL

I'm having trouble formulating my MySQL statement / query string. I have a table (see sample below)
It's a sample table containing gender, age and report_requested fields. What I would like to have as an output is something like this:
20 years old, male | Total number of users | Total who requested min 1 report | total who requested 2 reports | total 3 or more reports
20 years old female | Total number of users | Total who requested min 1 report | total who requested 2 reports | total 3 or more reports
20 years old combined | Total number of users | Total who requested min 1 report | total who requested 2 reports | total 3 or more reports
21 years old, male | Total number of users | Total who requested min 1 report | total who requested 2 reports | total 3 or more reports
21 years old female | Total number of users | Total who requested min 1 report | total who requested 2 reports | total 3 or more reports
21 years old combined | Total number of users | Total who requested min 1 report | total who requested 2 reports | total 3 or more reports
... etc.
But I'm having a hard time with it. What I just know is to determine the number of users who requested (1,2,3,...etc) credit reports given the gender and age.
Here's what I used:
SELECT COUNT(*) as cnt, report_requested
FROM sampletable WHERE age = '39'
AND gender = 'M' GROUP BY report_requested
Here's the result:
It just return the data for 20 yrs old male, number of users requested 1 credit report, 2 credit reports up to 8 (but this is also wrong since it should combine the number of users who requested 3 credit reports or more)
Can anybody here help me or give me an idea on how I could accomplish this?
Your GROUP BY clause is actually both age and gender since you are trying to aggregate for these two. The way to think about it is that you want exactly one row per age and gender, i.e. 1 row for male/20 yrs, 1 row for female/20 yrs, 1 row for male/21 yrs, etc. So you would do:
GROUP BY age, gender
And instead of report_requested column, I think you need to SUM(report_requested) with a condition on the number of reports requested. This is handled in SQL via the CASE clause. So your query would look like this:
SELECT AGE, GENDER,
SUM(CASE WHEN report_requested = 1 THEN 1 ELSE 0 END) AS 'Total who requested 1 report',
SUM(CASE WHEN report_requested = 2 THEN 1 ELSE 0 END) AS 'Total who requested 2 reports',
SUM(CASE WHEN report_requested >= 3 THEN 1 ELSE 0 END) AS 'Total who requested 3 or more reports'
FROM sampletable
GROUP BY AGE, GENDER
Let me know how it goes. I removed the WHERE clause because I assumed that was for testing only.
EDIT: Updated after the comments below, that it's not the total requested rather total who requested 1 report, total who requested 2 reports, etc.