MySQL Get results from multiple tables based on a date - mysql

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;

Related

How to Group result from 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.

MySQL: Aggregate weekly statistics with substatics (subqueries)

I would like to gather weekly statics on a MySQL-Table.
The table itself has the following structure:
user_id action_id created
0 123 2017-01-01 00.00:00
0 124 ...
1 123 ...
... ... ...
I would like to aggregate the weekly statics for:
How many user where active per week
This is rather simple:
SELECT
YEARWEEK(created) as week,
COUNT(DISTINCT user_id) AS count
FROM data
GROUP BY YEARWEEK(created);
Additionally I could apply a sorting.
The result looks like:
week count
201701 2
201702 3
How many user where active per week for the very first time
I thought about solving it by using a subquery
SELECT
YEARWEEK(created) as week,
COUNT(DISTINCT user_id) AS count,
(
SELECT
COUNT(DISTINCT d2.user_id)
FROM data d2
WHERE YEARWEEK(d2.created) = week
AND NOT EXISTS (SELECT 1 FROM data d3
WHERE YEARWEEK(d3.created) < week AND d2.user_id = d3.user_id)
) as countNewUsers
FROM data d1
GROUP BY YEARWEEK(created);
How many junior user where active per week
Junior users were active between 1 and 10 times before the related week
Similar to the one above, but with other subquery
How many power user where active per week
Senior users were active more than 10 times before the related week
This works as expected, but has a rather poor performance, since the subquery is evaluated before the grouping happens. With millions of rows in a table, this takes ages.
Does anybody have a better solution for this query, ideally returning all values in single result set?
I think all of your queries could derive from one 'intermediate' table. It would contain (yearweek, userid, count).
Users active per week: Pretty much the same query, but faster from this table.
Active for first time: Self-join ON userid and desired week versus MIN(yearweek)
Uses before the target week: ... SUM(count) WHERE ... < week GROUP BY userid
Use the above to determine which userids of Junior/Power.

MySQL - Chaining multiple SQL commands

I've looked upon multiple threads but can't seem to find a desirable answer to my question. I am creating a system with a scheduler in it and I need multiple chains in order for the query to return an answer. So here is the scenario. A user needs to register and upon registration, the user is presented with a date.
I have users table where users(obviously) are listed. One column here has the date.
There is also a date table where the dates are stored. Each date can only occupy 30 persons.
The date table also has the availability column. If the date is available, it is labeled 1. If the date has expired (the current date is higher than this date), it is labeled 0.
for example, i have dates Jan 1, Jan 2 and Jan 3 and the current date is Jan 2. Obviously, Jan 1 should be expired. That wouldn't be included in the list so I will set the availability to 0 (yes, manually). There is only Jan 2 and Jan 3. I also need to find if Jan 2 has accommodated 30 people. Else, I need to put him to Jan 3. I got a bunch of parts of the codes that I don't know how to chain.
Expected Output :
query1 (Jan 2 and Jan 3 should be the result)
SELECT * FROM rooms WHERE availability = 0
RoomID Room Date Room Availability
1 Jan 1 1
2 Jan 2 0
3 Jan 3 0
query2 - (count people assigned in specific rooms)
SELECT COUNT(RoomAssigned) FROM users
Users RoomAssigned
Jack 2
Eddie 2
query3 - (system should be able to locate the first room that is available)
if (query2 results<30)
put new user to rooms from result in query1
If ever the chaining I was looking for would possibly be not advisable, I am open for different suggestions. Thanks. :)
Your question seems to be very confused about what tables you have and what's in them, and I don't see how your sample queries can produce the output you showed. But it seems like this query will do what you want:
SELECT *
FROM rooms
WHERE availability = 1
AND roomID NOT IN (
SELECT roomAssigned
FROM users
WHERE availability = 1
GROUP BY roomAssigned
HAVING COUNT(*) >= 30)
ORDER BY roomDate
LIMIT 1
The subquery finds all the rooms that are filled, and then we exclude those from the main query. Then we sort the remaining rooms by date, and select the first one with LIMIT 1.
I think you're going to want something like this:
SELECT r.[RoomID],
r.[Room Date]
FROM rooms r
LEFT JOIN users u
ON r.[RoomID] = u.[RoomAssigned]
WHERE r.[Room Date] >= CURDATE()
GROUP BY r.[RoomId], r.[Room Date]
ORDER BY r.[Room Date], r.[Room Id]
HAVING COUNT(u.[RoomAssigned]) < 30
LIMIT 1
I haven't tested it, so it may require some tweaking. It's like #Barmar's answer, only using a join instead of a nested select. I also checked the availability based on the current date, not the availability column, which I don't think should be stored in the database, because it can be determined based on the Room Date.

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;

Calculating anniversaries of employees with their joining dates

As part of database testing, we are to verify if the data is correctly rendered onto the webpage from database.
We have a table called 'emp_details' which stores employee details. We store joining date of an employee in it. Now, using this joining date field, I need to get a list all the employees who have a start date or anniversary date within the last ten days.
I tried various combinations of DATEDIFF() in MySQL but did not succeed.
The format on the webpage would look like this:
Name Start Date Years
----------------------------------
William 07/25/2004 8
Gordon 07/22/2007 5
Jill 07/26/2009 3
Could anyone please help me with the query for MySQL DB.
Thanks,
select * from
employees where
dayofyear(`start date`) between dayofyear(curdate())-10 and dayofyear(curdate())
You can use following in WHERE clause
DAYOFYEAR(CURDATE()) - DAYOFYEAR(start_date) < 10
OR is greater than (365 - 10)