How to Group result from mySQL - mysql

My Table:
datetime. employment. name
2019-11-25 12:32:12. office. Michael Jackson
2020-01-31 12:32:22. production. Jenny Darling
2019-12-25 12:32:12. office. Michael Jackson
etc.
This is a "time registering" table, so names must be DISTINCT for each mounth. (How many unique names is there every month grouped by month and employment)
Now i'd like to create a table that will show how many employees there was in every month by year.
So the table will look like:
Year & Month. Employment. Number (Unique names)
-------------------------------------
2019-01. Office. 50
2019-01 Production. 35
2019-02. Office. 45
2019-02. Production. 36
And so on for this and prev year (2019 & 2020)
Something like:
SELECT * FROM table COUNT(DISTINCT(name)) AS number GROUP BY datetime AND employment

You seem to want aggregation... but your query is invalid in several regards. I think you want:
select
date_format(datetime, '%Y-%m') yr_month,
employment,
count(distinct name) no_unique_names
from mytable
group by yr_month, employment
This gives you on row per year/month and employment, with the corresponding count of distinct names.

Related

Number of rows returned when adding before/after date logically inconsistant

I have a database containing information about a students visit to our tutoring center. Each time a student visits a record is produced which includes their names, their student number the date they visited, what they were there for and how long they were there.
We create new tables for each term
I was asked to get an unduplicated count of how many students were there during a certain term so I run the following.
SELECT * FROM `tutoringdata_201350` group by `anum`
anum being the students unique identification number, which returns 524 results out of 5525 total records. In theory that should be my unduplicated count.
I was then asked to get records before and after a certain date in that same table, so I run.
SELECT * FROM `tutoringdata_201350` WHERE `cDate` <= "09/30/2013" group by `anum`
Which works, so far as the date is concerned and no duplicate people are returned so far as I can see in the results window if I sort by the anumber they are all unique. BUT the total number of results returned is 375
So to get students after that date I run
SELECT * FROM `tutoringdata_201350` WHERE `cDate` > "09/30/2013" group by `anum`
which also appears to work, no duplicated students in the returned results but total number of returned results is 428.
375 + 428 is 803 not 524 which I would expect. I'm having trouble following the logic, which of the 2 different types of queries are producing an inaccurate number of results.
You are misusing the pernicious nonstandard MySQL extension to GROUP BY. http://dev.mysql.com/doc/refman/5.6/en/group-by-handling.html
You probably want something like this;
SELECT COUNT(DISTINCT anum) unique_students
FROM `tutoringdata_201350`
WHERE cDate <= 'whatever'
You could also do this to find out how many visits each student made.
SELECT COUNT(*) visits,
anum
FROM `tutoringdata_201350`
WHERE cDate <= 'whatever'
GROUP BY anum
You are also, I think, making a mistake in the way you are comparing dates.
MySQL uses an internal DATE and DATETIME format. If you want to compare such data items in your table to a text-string constant, you need to use the correct format -- YYYY-MM-DD -- for that string. For example:
WHERE cDate <= '2013-09-30'
The comparison in your example isn't correct. Edit. If your dates are stored as text strings as MM/DD/YYYY, you need to use the following sort of comparison.
WHERE STR_TO_DATE(cDate, '%m/%d/%Y') <= '2013-09-30'
This will convert your legacy date strings to DATE format. Then the comparison will work. If you don't do this MySQL is just comparing strings to strings. (You may, or may not, luck out if the years don't vary.)
Now, your counts of unique students before and after the first of October do not necessarily sum up to the count of unique students for the whole term. Here's an example.
Joe Sept 28
Joe Sept 29
Mary Sept 30
Henry Sept 30
Joe Oct 1
Stephen Oct 1
Overall there are four distinct students. In Sept there are three. In October there are two. If you add those two numbers you get five. That's more because you're double-counting Joe by adding those two numbers.

Obtain date difference based on different columns id

I have an employee database that shows me peer week the couple of employees who work together,
for the next week i need to know how many rest days that employee had...
Every employee had an unique ID
Depending of the week you work as Employee1 or Employee2
The calculations of the rest days starts in week 2 so 9999 is the default number if there is no restDay
so, let's take for example the employee with id 2, in the week 1 he works as emp2, but the next week he works as emp1. I need to obtain the rest days, which in this case it will be for the emp1...
the columns in my db are
1. id
2. employee1
3. employee2
4. week
5. emp1_restDay
6. emp2_restDay
7. date_time
db example
Bad data structure, but I guess you have to deal with it. You need to get one column per employee, which you can do using union all:
select employee, sum(restDay)
from ((select id, week, employee1 as employee, emp1_restDay as restDay, datetime
from table t
) union all
(select id, week, employee2 as employee, emp2_restDay as restDay, datetime
from table t
)
) t
group by employee;

Is it possible to combine 'DISTINCT' and 'COUNT' queries, so that I can see how many times each distinct value appears?

Say that my database was like IMDb, a huge collection of movie titles and their release dates.
TITLE DATE
Terminator 2 1991
Tron 1982
Karate Kid 1984
Silence of the Lambs 1991
and I want to issue a query that will return to me data in the form
1991 2
1982 1
1984 1
Meaning that there are two rows that have '1991' in the year field, one row that has '1982' in that field, etc.
Is there a way I can do this purely with an SQL query, or should I be writing something in my program itself to generate this data?
Instead of distinct + count it would be group by
select field, count(*) from table group by field
When you do a COUNT and GROUP BY, the DISTINCT isn't necessary because all the duplicates are already eliminated.
select date as year ,count(*) as movie_count from table group by date;

MySQL Get results from multiple tables based on a date

I am creating a personnel database and have multiple tables relating to a user that include things like medical examinations, passports, vaccinations, memberships etc.
Each of these tables contains an expiry record which I want to query all tables on. Basically I want to have a list of items that are going to expire in a certain time, something like:
John - Passport expires in 1 month
Emma - Vaccination expires in 1 month
Carol - Vaccination expires in 3 weeks
Josh - Medical expires in 2 weeks
James - Passport expires in 3 days
What is the best way to do this, can it somehow be done in a single query?
Thanks in advance
It could be done in a single query using union:
(SELECT name, 'passport', expiry_date FROM table_passport WHERE ...)
UNION ALL
(SELECT name, 'vaccination', expiry_date FROM table_vaccinations WHERE ...)
UNION ALL
(SELECT name, 'medical', expiry_date FROM table_medical WHERE ...)
ORDER BY name;

MYSQL - multiple count statments

I'm trying to do a lookup on our demographioc table to display some stats. However, since out demographic table is quit big I want to do it in one query.
There are 2 fields that are important: sex, last_login
I want to be able to get the total number of logins for various date ranges (<1day ago, 1-7 days ago, 7-30 days ago, etc) GROUPED BY sex
I right now know how to do it for one date range. For example less than 1 day ago:
SELECT sex, count(*) peeps
FROM player_account_demo
WHERE last_demo_update > 1275868800
GROUP BY sex
Which returns:
sex peeps
----------------
UNKNOWN 22
MALE 43
FEMALE 86
However I'd have to do this once for each range. Is there a way to get all 3 ranges in there?
I'd want my end result to look something like this:
sex peeps<1day peeps1-7days peeps7-30days
Thanks!
IMPORTANT NOTE: last demo_update is the epoch time (unix time stamp)
SELECT sex,
SUM(IF(DATEDIFF(NOW(),last_login) < 1,1,0)),
SUM(IF(DATEDIFF(NOW(),last_login) BETWEEN 1 AND 7,1,0)),
SUM(IF(DATEDIFF(NOW(),last_login) BETWEEN 7 AND 30,1,0))
FROM player_account_demo
GROUP BY sex
You want to use a Pivot Table.