I have a table like this: Table Name: Accounting
year
acc
value
2018
in
500
2018
out
500
2019
in
600
2019
out
800
I need to show up to 10-year slots with the highest value (i.e in + out). For example, in this case, 2019 is the highest, my query should show
year
Max Value
2019
1400
My current SQL code is:
SELECT year,acc, MAX(value) as max_value
FROM Accounting
group by year,acc
LIMIT 10
How can I get the desired result?
You need SUM() and ORDER BY:
SELECT year,acc, SUM(value) as sum_value
FROM Accounting
GROUP BY year
ORDER BY sum_value DESC
LIMIT 1;
If you want only ten years to be considered, you need a WHERE clause, for instance:
SELECT year, SUM(value) as sum_value
FROM Accounting
WHERE year >= 2010
GROUP BY year
ORDER BY sum_value DESC
LIMIT 1;
I may be misunderstanding your question, but what it appears you are attempting to complete the following steps.
You are trying to SUM by year, regardless of account type, the amount in the value column.
You are trying to show only the years with the 10 highest summed values over some specified period of time.
One way to approach this would be as follows
SELECT year, SUM(value) as annual_value
FROM Accounting
GROUP BY year
ORDER BY annual_value desc
LIMIT 10
You have to use the SUM() not the MAX(), because you don't want only the highest value, but the total, and then you only have to GROUP BY them by year
SELECT year,sum(value) as max_value
FROM Accounting
group by year
LIMIT 10;
Here's the result:
+------+-----------+
| year | max_value |
+------+-----------+
| 2018 | 1000 |
| 2019 | 1400 |
+------+-----------+
Related
I have a table that consists of the following data, I would like to know whether it is possible to get a Month (i.e Jan, Feb) wise count of Reservations that happened and also Month wise count for each location.
PNR
Location
Reservation Date
Passenger Name
Travel Date
PNR81239087
Mumbai
2019-10-01 12:19:00
Ram
2019-11-06 15:59:00
PNR81239090
Kerala
2019-10-01 15:18:00
Kannan
2019-12-03 19:18:00
PNR812390199
Mumbai
2019-10-01 17:19:00
Ram
2019-11-01 18:39:00
For example,
Month Wise Count (including all locations) should look something like this,
Month
Count
October-2019
3
Monthwise count for each location:
Month
Count
Location
October-2019
2
Mumbai
October-2019
1
Kerala
I think this will work for you
Month Wise Count (including all locations) :
select MONTHNAME(Reservation_Date) as Month, count(*)
from yourTable
group by MONTHNAME(Reservation_Date)
Monthwise count for each location :
select MONTHNAME(Reservation_Date) as Month, count(*), Location
from yourTable
group by MONTHNAME(Reservation_Date), Location
EDIT IN QUESTION :
Changed to Group by Year and Month in one column:
Month Wise Count (including all locations) :
select concat(MONTHNAME(Reservation_Date),'-',Year(Reservation_Date)) as Month-Year,
count(*) as Count
from yourTable
group by concat(MONTHNAME(Reservation_Date),'-',Year(Reservation_Date))
Monthwise count for each location :
select concat(MONTHNAME(Reservation_Date),'-',Year(Reservation_Date)) as Month-Year,
count(*) as Count, Location
from yourTable
group by concat(MONTHNAME(Reservation_Date),'-',Year(Reservation_Date)), Location
You can use this :
/*Location-wise*/
SELECT DATENAME(MONTH, ReservationDate) as [Month],
COUNT(*) AS Count,
Location
FROM Temp
GROUP BY DATENAME(MONTH, ReservationDate), Location
ORDER BY Location DESC
/*All locations*/
SELECT DATENAME(MONTH, ReservationDate) as [Month],
COUNT(*) AS Count
FROM Temp
GROUP BY DATENAME(MONTH, ReservationDate)
You can see this working here : All locations and Locations-wise
I have the following database schema
ID creation_date
1 2019-06-03
2 2019-06-04
3 2019-06-04
4 2019-06-10
5 2019-06-11
I need to find out the total size of the table group by week. The output I am looking for is something like
year week number_of_records
2019 23 3
2019 24 5
I am writing the following query which only gives me number of record created in each week
> select year(creation_date) as year, weekofyear(creation_date) as week,
> count(id) from input group by year, week;
Output I get is
year week number_of_records
2019 23 3
2019 24 2
Take a look to window (or analytic) functions.
Unlike aggregate functions, window functions preserve resulting rows and facilitate operations related to them. When using order by in over clause, windowing is done from first row to current row according to specified order, which is exactly what you need.
select year, week, sum(number_of_records) over (order by year, week)
from (
select year(creation_date) as year, weekofyear(creation_date) as week,
count(id) as number_of_records
from input group by year, week
) your_sql
I guess you will also need to reset sum for each year, which I leave as exercise for you (hint: partition clause).
For versions prior to 8.0...
Schema (MySQL v5.7)
CREATE TABLE my_table
(ID SERIAL PRIMARY KEY
,creation_date DATE NOT NULL
);
INSERT INTO my_table VALUES
(1 , '2019-06-03'),
(2 , '2019-06-04'),
(3 , '2019-06-04'),
(4 ,'2019-06-10'),
(5 ,'2019-06-11');
Query #1
SELECT a.yearweek
, #i:=#i+a.total running
FROM
(SELECT DATE_FORMAT(x.creation_date,'%x-%v') yearweek
, COUNT(*) total
FROM my_table x
GROUP BY yearweek
)a
JOIN (SELECT #i:=0) vars
ORDER BY a.yearweek;
| yearweek | running |
| -------- | ------- |
| 2019-23 | 3 |
| 2019-24 | 5 |
---
View on DB Fiddle
You seem to want a cumulative sum. You can do this with window functions directly in an aggregation query:
select year(creation_date) as year, weekofyear(creation_date) as week,
count(*) as number_of_starts,
sum(count(*)) over (order by min(creation_date)) as number_of_records
from input
group by year, week;
so I have a table "records" like this:
name month year
Rafael 9 2018
Rafael 5 2018
Rafael 10 2017
And I want to get my last records (Rafael, 9, 2018). I thought about summing the month and the year and getting the max of that sum like this:
select * from records, max(month + year) as max_date
But doesn't seem to be right. Thanks for help
Using ORDER BY clause, you can get the highest year and month combo. Try the following:
SELECT *
FROM records
ORDER BY year DESC, month DESC
LIMIT 1
Do you mean the output of the follwing?
select *
from records
order by year desc, month desc
limit 1
In general, it would be more useful to use one DATE or DATETIME column type for this purpose where you can extract year and month if you want.
Use concat if you want to concat max month and max year
Select name ,concat (concat( max(month), '-'),max(year)) from records
Group by name
but if you want just year wise max year date information then use below
Select * from records
order by year desc
limit 1
https://www.db-fiddle.com/f/sqQz1WEEAukoWEWkbxBYxe/0
name month year
Rafael 9 2018
I have this table:
-----------------------------------------------------------
| id | name | date | count | balance |
-----------------------------------------------------------
1 a 0000-00-00 1 10
2 b 2014-10-02 1 20
3 c 2014-09-01 1 30
4 d 2014-09-16 1 40
I need to get the SUM of the four count & balance column on my SELECT, then order it by the date in ascending but I need to make sure it should not be the 0000-00-00. I tried this syntax but it does not order the date the way I wanted.
SELECT
date,
SUM(count) AS deposit_counts,
SUM(balance) AS balance_sum
FROM tbl
ORDER BY date ASC
My expected output:
-------------------------------------------
| date | count | balance |
-------------------------------------------
2014-09-01 4 90
Use MIN and NULLIF functions:
SELECT
MIN(NULLIF(date, '0000-00-00')) AS min_date,
SUM(count) AS deposit_counts,
SUM(balance) AS balance_sum
FROM tbl
Test it here: http://sqlfiddle.com/#!2/d43acf/1
I wish I understood the point in having a 0000-00-00 date as opposed to having null so only one possibility needs ruling out... Anyway at first I would assume you might want to get the total balances of each day and would require a query along these lines
SELECT
date,
sum(count) AS deposit_counts,
SUM(balance) AS balance_sum
FROM tbl
WHERE date <> '0000-00-00'
GROUP BY date
ORDER BY date
which would output
2014-09-01 1 30
2014-09-16 1 40
2014-10-02 1 20
but as it stands it appears you don't, I'm not one hundred percent sure what your ultimate goal is in terms of future querying so I will guess you want a historical value of balances up to the current date, ruling out the weird zero date thing. In which case you might want a greater than WHERE clause, and presumably just the lowest value in the date column to show the total from this date like so:
SELECT
min(date) AS date,
sum(count) AS deposit_counts,
SUM(balance) AS balance_sum
FROM tbl
WHERE date > '0000-00-00'
since it would ignore the invalid date it will return
2014-09-01 3 80
I hope this is of some use.
Edit:
if you absolutely require all values then you will want to use a subquery to retrieve and rule out the exceptional date result like so:
SELECT
(SELECT min(date) FROM tbl WHERE date > '0000-00-00') AS date,
sum(count) AS deposit_counts,
SUM(balance) AS balance_sum
FROM tbl
or as above, nullif on your date query should work too
I have 2 mysql tables like bellow:
Table income Table expense
id amount date id amount date
1 200 2011-12-10 1 100 2011-12-21
2 300 2011-12-14 2 150 2012-01-01
3 500 2012-01-05 2 200 2012-01-03
I want to get data in this way:
month profit
december, 2011 400
january, 2012 150
Is this possible in a single query?
What you want is a union with some date magic for the aggregate:
select
date_format(x.date, '%M %Y') as `month`,
sum(amount) as profit
from
(select amount, date
from income
union all
select amount*-1 as amount, date
from expense
) x
group by
date_format(x.date, '%M %Y')
The specific thing we're using here is date_format to get the dates the way we want it. Also, we're multiplying amount by -1 when it comes from expense to make the calculation correct. Of course, we could have returned different columns for income and expense and then did the math on them in the sum, such as sum(x.income_amount, x.expense_amount), but there's no need to do that when you can just quickly do a *-1 to the column on before it hits the sum.
The other important thing is the group by. Here, we're grouping by a function that formats the date as Month, YYYY, so it will get the divisions you're looking for.