Reputation: 55
Given a table within a MySQL schema with a format similar to: person_id | creation_date Example data:
p1 | 08-12-1995
p2 | 04-11-2002
p3 | 12-31-2007
...
I am having difficulty understanding the syntax to do the following functionalities: 1. I want to count the number of people based on their creation date For example, I want to create a table that is GROUPED BY the year and will have a supporting column that has the COUNT of all the people that were created within that year. 2. Use an aggregate function that will be able to calculate the delta between two years' values based on the new GROUPED BY table i.e.
Year | # of people | Delta
1995 | 20 |
1996 | 22 | +10%
1997 | 18 | -18%
...
I'm new to MySQL and the syntax still confuses me. I don't know if creating a new table GROUP'd based on year is the most effective solution to go about the solution and I am unsure how I would calculate the delta in a table into my own.
Upvotes: 1
Views: 26
Reputation: 33935
You can also do something like the following, but on larger data sets, an answer something like Uueerdo's should be faster.
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
( year INT NOT NULL
, person VARCHAR(12) NOT NULL
, PRIMARY KEY(year,person)
);
INSERT INTO my_table VALUES
(1995,'Adam'),
(1995,'Ben'),
(1995,'Charlie'),
(1995,'Dan'),
(1996,'Edward'),
(1996,'Fred'),
(1996,'Gary'),
(1996,'Henry'),
(1997,'Inigo'),
(1997,'James'),
(1997,'Kevin'),
(1997,'Leonard'),
(1998,'Michael'),
(1998,'Noah'),
(1998,'Oliver'),
(1998,'Patrick'),
(1998,'Quentin'),
(1998,'Robert'),
(1999,'Stephen'),
(1999,'Thomas'),
(1999,'Umberto'),
(2000,'Victor'),
(2000,'Walterr'),
(2001,'Xavier'),
(2002,'Yanick'),
(2003,'Zac');
SELECT a.*
, a.n/b.n * 100 pct_diff
FROM
( SELECT x.year, COUNT(*) n FROM my_table x GROUP BY year ) a
LEFT
JOIN
( SELECT x.year, COUNT(*) n FROM my_table x GROUP BY year ) b
ON b.year = a.year - 1;
+------+---+----------+
| year | n | pct_diff |
+------+---+----------+
| 1995 | 4 | NULL |
| 1996 | 4 | 100.0000 |
| 1997 | 4 | 100.0000 |
| 1998 | 6 | 150.0000 |
| 1999 | 3 | 50.0000 |
| 2000 | 2 | 66.6667 |
| 2001 | 1 | 50.0000 |
| 2002 | 1 | 100.0000 |
| 2003 | 1 | 100.0000 |
+------+---+----------+
Upvotes: 0
Reputation: 15941
Something like this should work, but take care to not change the order of the result columns (they, unofficially, evaluate left to right).
SET @lastCount := null;
SELECT creationYear AS `Year`
, IF(@lastCount IS NULL
, ''
, CONCAT(ROUND(100*((pCount/@lastCount)-1), 0), '%')
) AS `Delta`
, @lastCount := pCount AS `# of people`
FROM (
SELECT YEAR(creation_date) AS creationYear, COUNT(1) AS pCount
FROM theTable
GROUP BY creationYear
ORDER BY creationYear
) AS subQ
Upvotes: 1