How to get a starting and ending reservation date for a group in mysql database? - mysql

I have a database called global and in that database I have groups table and reservations table, and the relation is one to many (one group can have many reservations).
What I wanted to do was to display the group name along with the first check in date and the last check out date of the reservations.
I am developing using codeigniter 3.x.

Assuming you have this structure of tables:
GROUPS
+--------+-----------+
| id | Name |
+--------+-----------+
and:
RESERVATIONS
+--------+-----------+------------------------------+------------------------------+
| id | Groupid | ReservationCheckinDate | ReservationCheckoutDate |
+--------+-----------+------------------------------+------------------------------+
the SQL to get the desired result would be:
SELECT MIN(ReservationCheckinDate), MAX(ReservationCheckoutDate), Name FROM RESERVATIONS
JOIN GROUPS ON GROUPS.id = RESERVATIONS.Groupid
GROUP BY Name
ORDER BY Name;
hope it helps

Related

MySQL 5.7 return all columns of table based on distinct column

I just upgraded to MySQL 5.7 and unfortunately for me, some of the functionality of GROUP BY is gone. I wanted to select all movies from my movies table with as long as the movies.id of type int is not a duplicate. My previous query in MySQL 5.6 was:
SELECT *
FROM movies
WHERE movies.title LIKE '%example%'
GROUP BY movies.id
If I had two movies with the same id, it would only display one movie, instead of that movie and its duplicates.
When I upgraded to MySQL 5.7, the GROUP BY gave me errors and I was instead told to use ORDER BY. However this query:
SELECT *
FROM movies
WHERE movies.title LIKE '%example%'
ORDER BY movies.id
Does return duplicate movies. So, is there a way to filter this out, and only return a row if it isn't a duplicate?
Edit: For example if this is my movies table:
movies
==================
| id | title |
==================
| 1 | example |
------------------
| 2 | example |
------------------
| 1 | example |
------------------
Here is the output of each query:
Previous query result (with MySQL 5.6)
=======
1 | example
2 | example
New query result (with MySQL 5.7 and ORDER BY)
=======
1 | example
1 | example
2 | example
I want the final result to contain no duplicates (so the result should look like the first query result).
Edit 2: I understand I was sort of abusing the way MySQL handled GROUP BY. Unfortunately, I do not have much experience with MySQL and got that answer from StackOverflow. I would just like to return all columns in my table that do not contain duplicate ids.
I believe would be easy to use distinct keyword
SELECT distinct movies.*
FROM movies
WHERE movies.title = 'example'

How can I make a stored procedure to update one column in one table based on the order of rows from another table?

I have two tables
Users:
user | name | country | rank | country_rank | points
1 | frank | US | to be determined | to be determined | to be determined
Awards:
awarded_to | points_awarded
1 | 10
1 | 30
How can I make a stored procedure to update the users total points based off of the points from awards, then their rank and country_rank respectively based off of the order of the points (i.e. rank 1 would be the user with the most points)?
I considered making a PHP script and using a crontab to call it occasionally that would just select the info and do the math etc in PHP, but stored procedures seems much more practical for my use-case.
create temporary table awardsum (user int, total int); #temp
insert into awardsum
select a.awarded_to, sum(a.points_awarded)
from users u
inner join awards a on u.user=a.awarded_to
group by a.awarded_to;
update users
join awardsum on users.user=awardsum.user
set users.points = awardsum.total;
SELECT #row:=0;
UPDATE users
SET rank = (#row:=#row+1)
ORDER BY points desc;
drop table awardsum;

mySQL table with EMP_ID and lots of timestamps

I'm new to relation databases and mySQL, I am trying to develop a database for employees, that logs all the times its employees access the system(shown by recording the timestamp of everytime it access the system).
So when the employee accesses the system, the current timeStamp is recorded, and the next time they acess it that current timestamp is also recorded. The idea is that i can go back and query how many times in a day an employee accessed the system or week and so on, for any employee.
so far i have:
EMP_ID | F_Name | L_Name | TimeStamp
-------------------------------------
1222 | joe | blogs | 12.03.22
1222 | joe | blogs | 12.44.34
1352 | carl | mansy | 19.33.22
and so on, i would like to know if there is a way to have just one emp_id show up with all the timestamps below, or do i need another table? or can i just have the data base like this?
Obviously this will grow in size a lot, so would it be better to have a table for every emp_id?
Thanks in advance Jonny
You should have 2 tables
first one is the employee table
emplyee : EMP_ID | F_Name | L_Name
the second one is the log table
employee_log : EMP_ID | TimeStamp
the first table will store the data of the empolyee
the second will store just the log of this employee
and if you want to retrieve the logs you just need to join betwen these tables
select * from employee
left join employee_log on employee.EMP_ID = employee_log.EMP_ID
You should have 2 tables one to store employee data and the other to store
the log data
employee : EMP_ID | F_Name | L_Name
employee_log : EMP_ID | TimeStamp
Assuming all data is stored in table named my_log_table, To see all timestamps for an EMP_ID 12222, query it like
select TimeStamp from my_log_table where EMP_ID = 12222
Having all logs in same table would be scalable and easier to use.
Issues with having multiple log tables:
For each new user, you have to manually create a new table
Privileges have to be granted to this script/user to query the new
table created for a new user
If EMP_ID changes, then you have to track and change table names
Moreover, you are not saving any space other than one column of EMP_ID of
combined log table
I hope it would be better if you maintain your table as below.
EMP_ID | TimeStamp
1222 | 12.03.22
1222 | 12.44.34
1352 | 19.33.22
So, while retrieving you can display as cross table like below
1222 | 1352 |
12.03.22 | 19.33.22
12.44.34 |

MySQL counting number of max groups

I asked a similar question earlier today, but I've run into another issue that I need assistance with.
I have a logging system that scans a server and catalogs every user that's online at that given moment. Here is how my table looks like:
-----------------
| ab_logs |
-----------------
| id |
| scan_id |
| found_user |
-----------------
id is an autoincrementing primary key. Has no real value other than that.
scan_id is an integer that is incremented after each successful scan of all users. It so I can separate results from different scans.
found_user. Stores which user was found online during the scan.
The above will generate a table that could look like this:
id | scan_id | found_user
----------------------------
1 | 1 | Nick
2 | 2 | Nick
3 | 2 | John
4 | 3 | John
So on the first scan the system found only Nick online. On the 2nd it found both Nick and John. On the 3rd only John was still online.
My problem is that I want to get the total amount of unique users connected to the server at the time of each scan. In other words, I want the aggregate number of users that have connected at each scan. Think counter.
From the example above, the result I want from the sql is:
1
2
2
EDIT:
This is what I have tried so far, but it's wrong:
SELECT COUNT(DISTINCT(found_user)) FROM ab_logs WHERE DATE(timestamp) = CURDATE() GROUP BY scan_id
What I tried returns this:
1
2
1
The code below should give you the results you are looking for
select s.scan_id, count(*) from
(select distinct
t.scan_id
,t1.found_user
from
tblScans t
inner join tblScans t1 on t.scan_id >= t1.scan_id) s
group by
s.scan_id;
Here is sqlFiddle
It assumes the names are unique and includes current and every previous scans in the count
Try with group by clause:
SELECT scan_id, count(*)
FROM mytable
GROUP BY scan_id

MySQL Query with reference parameter from another table

I apologise in advance if this might seem simple as my assignment needs to be passed in 3 hours time and I don't have enough time to do some further research as I have another pending assignment to be submitted tonight. I only know the basic MYSQL commands and not these types. Please help.
Say that I have two tables:
________________ _________________
| customers | | agents |
|________________| |_________________|
|(pk)customer id | |(pk) agent_id |
|(fk) agent_id | | first_name |
| first_name | | last_name |
| last_name | | address |
|________________| |_________________|
Basically I would just like to know how to query something like: (in incorrect terms)
SELECT * FROM customers WHERE agent_id = '(agent_id of Michael Smith from the AGENTS table)'
obviously I only have the agent_id of the agent and i can directly call it if i know what the agents name is based on the id like:
SELECT * FROM customers WHERE agent_id = '4'
but how can i query it by submitting the agent first name and last name as parameter?
(first name and last name because agents can have the same names, or even same last names)
Remember your foreign key does not help you building the query, you have to tell the database what you want in the query (however, a foreign key can help data spread across tables more consistent).
You can use a JOIN here.
You can implement it like this:
SELECT *
FROM customers C
INNER JOIN agents A ON C.agent_id = A.agent_id
WHERE A.last_name = 'Smith'
AND A.first_name = 'Michael';
You can do it without a join as well.
select *
from customers
where customers.agent_id in (
select agents.agent_id
from agents
where agents.first_name = 'Michael' and agents.last_name = 'Smith'
);