MySQL get newest data of user from every table - php

I have 6 tables to store my user data
tbl_user_name
uuid | username | date (unix time)
-----------------------------------------
0 | lisha.s | 1489857236
1 | titami | 1485853232
2 | mathew | 1442853636 <----|> Users can change their username
3 | sandarjun | 1489857239 |> so i need to get the uuid by the
2 | mathew_kar | 1575456274 <----|> newest username which is given
tbl_user_fullname:
uuid | fullname | date (unix time)
-----------------------------------------
0 | Lisha Simonette | 1489857236
1 | Titus Amiran | 1481256345
2 | Mathew Karolina | 1489234455
3 | Sandhya Arjun | 1489857239
0 | Lisha Karolina | 1599999999
tbl_user_website:
uuid | website | date (unix time)
-----------------------------------------
0 | google.com | 1489857236
1 | titusamiran.com | 1489855234
2 | mathewk.net | 1489857432
3 | blod.sandhya.info | 1489857239
tbl_user_birthdate:
uuid | birthdate | date (unix time)
-----------------------------------------
0 | 02-05-1991 | 1489857236
1 | 05-08-1980 | 1489857123
2 | 09-09-1992 | 1489851334
3 | 17-02-1998 | 1489857239
tbl_user_follower:
uuid | follower_uuid
-----------------------
0 | 4
1 | 8
2 | 0
3 | 4
3 | 2
3 | 1
tbl_user_online:
uuid | last_seen (unix time)
-----------------------
0 | 1489855334
1 | 1589851111
2 | 1689857234
3 | 1789834539
i want to collect the uuid, the fullname, the website, the birthdate and the number of followers by a user with a given username. (i need to get the newest uuid of a username because the user can change the username).
The date column is the timestamp when they changes a value. for example in tbl_user_fullname: Lisha Simonette (uuid 0) married Mathew Karolina (uuid 2) so i neet to get the new fullname of Lisha (uuid 0) by the date column. And so on ... for tbl_user_website and tbl_user_birthdate .. even if they dont change their birthday often ;)
From the table tbl_user_online i only need the last_seen timestamp.
The value i give to the query is the username. the username should give out the uuid with which i can query the other tables.
Thank you very much for your help and sorry for my bad english ;)

The below query will resolve the question asked:
SELECT usr.uuid,
ful.fullname,
web.website,
brt.birthdate,
COUNT(fol.follower_uuid)
FROM tbl_user_name usr
JOIN tbl_full_name ful ON ful.uuid = usr.uuid
LEFT JOIN
tbl_full_name ful2 ON ful2.uuid = ful.uuid
AND ful2.time_stamp > ful.time_stamp
JOIN tbl_user_website web ON web.uuid = usr.uuid
LEFT JOIN
tbl_user_website web2 ON web2.uuid = web.uuid
AND web2.time_stamp > web.time_stamp
JOIN tbl_user_birthdate brt ON brt.uuid = usr.uuid
LEFT JOIN
tbl_user_birthdate brt2 ON brt2.uuid = brt.uuid
AND brt2.time_stamp > brt.time_stamp
JOIN tbl_user_follower fol ON fol.uuid = usr.uuid
WHERE usr.username = 'jack_2'
AND ful2.uuid IS NULL
AND web2.uuid IS NULL
AND brt2.uuid IS NULL
GROUP BY
usr.uuid,
ful.fullname,
web.website,
brt.birthdate
This query works by isolating the latest timestamp in a table that shares a common element in a row. In this case the uuid.
Here is the fiddle to see it working.
Here is a fiddle without the username filter
You have a bigger issue that you need to resolve, however. You should not be storing values like you are with timestamps.
I suggest you look into table triggers for update and insert statements. You should have a trigger set up to automatically insert an entry into an audit table that stores this information while keeping your core functioning tables small and orderly.
e.g create a table called tbl_user_name_audit. Have a trigger on tbl_user_name for updates. When a username is updated the previous value is inserted into the tbl_user_name_audit table with a before and after value as well as a timestamp and audit type (INSERT/UPDATE/DELETE).

Related

How to select rows from MySQL table with max values

I have a table with multiple rows for each customer and and a visit_date. The visit date can be null as well.
My tables are as below:
customers:
id | name | email
1 | John Doe1 | a.b#gmail.com
2 | John Doe2 | b.c#gmail.com
3 | John Doe3 | x.y#gmail.com
store_customers
id | customer_id | store_id | email_optedin | visit_date
1 | 1 | 1 | 1 | 2015-11-30
2 | 1 | 2 | 1 | 2016-05-08
3 | 1 | 3 | 1 | null
4 | 2 | 1 | 1 | 2015-04-30
5 | 2 | 2 | 1 | 2015-08-40
6 | 2 | 3 | 1 | 2015-12-12
7 | 3 | 1 | 1 | null
8 | 3 | 2 | 1 | null
9 | 3 | 3 | 1 | null
I am trying to retrieve customers who either have not had a visit to the any of the three stores or have not visited since a specified date (e.g. 2016-04-15).
I am expecting customers 2 and 3 but not 1.
I tried this query:
select distinct * from customers
inner join store_customers on store_customers.customer_id = customers.id
where customers.email != '' and
store_customer.store_id in (1,2,3) and customers.emailStatus not in ('Unverified','Bounced','Spammed')
and
(
store_customer.email_optedin = 1
and max(store_customers.visit_date) <= '2016-04-15'
or account_customer.visit_date is null
);
This does not work. I somehow need to, for the set of store ids), I need to select customers who have either not had any visit (all nulls for visit date for the specified stores) or the if one or more visit dates are available then compare the max date to the specified date.
I found similar questions but none of the answers has worked for me, mainly because of the requirement of selecting either those customers who have no visit or if they do atleast one, then to compare the latest visit date from the set of stores in the joined table.
I am trying to do this all in one query but if that is not possible then I can break it up as well. I also do not want to change the order of joins because there are many other things added on to this query and changing the order of joins may become a problem.
I really appreciate any help that can be provided.
Regards,
Waqar
Try this query
SELECT
customers.id,
customers.name,
MAX(store_customers.visit_date)
FROM
customers LEFT JOIN store_customers on customers.id = store_customers.customer_id
GROUP BY customers.id,customers.name
HAVING MAX(store_customers.visit_date) < '2016-04-15' OR MAX(store_customers.visit_date) IS NULL

How to display the previous row and next row from varchar value

I have hundreds rows of data. I want to get the previous row and the next row from the current item. I saw many examples here but none solve my problem.
My data key is a set of string (md5) which is unable to compare the greater or lower like the other does. Here's my resources.
---------------------------------------------------
| id| sid | name |
----+----------------------------------+----------|
| 1 | c81e728d9d4c2f636f067f89cc14862c + Mr.A |
----+----------------------------------+----------|
| 2 | eccbc87e4b5ce2fe28308fd9f2a7baf3 | Mr.B |
----+----------------------------------+----------|
| 3 | a87ff679a2f3e71d9181a67b7542122c | Mr.C |<current position
----+----------------------------------+----------|
| 4 | e4da3b7fbbce2345d7772b0674a318d5 | Mr.D |
----+----------------------------------+----------|
| 5 | 1679091c5a880faf6fb5e6087eb1b2dc | Mr.E |
--------------------------------------------------|
So, is there any way to get the previous row (Mr.B) and the next row (Mr.D) with mysql?
I've tried
SELECT * FROM table
WHERE sid < #sid
ORDER BY sid DESC
LIMIT 1
but it's not work because sid is uncomparable.

mySQL where exist or not exist select

Okay guys I have big problem with mySQL. I need to to do select that gets the free tables in the restaurant in specific time. Here are my tables:
tables:
+-------------+
| id | chairs|
+-------------+
| 1 | 3 |
| 2 | 5 |
| 4 | 10 |
| 7 | 12 |
| 10 | 6 |
+-------------+
and reservations:
+---------------------------------+
| id | table_id | start_datetime |
+----------------|---------------------+
| 1 | 3 | 2013-11-27 16:15:00 |
| 2 | 5 | 2013-11-27 19:00:00 |
+----------------|---------------------+
I try something like this
SELECT *
FROM wp_reserveit_tables,wp_reserveit_reservations
WHERE (wp_reserveit_tables.chairs = wp_reserveit_reservations.table_id
AND wp_reserveit_reservations.start_datetime - INTERVAL 1 HOUR >= '2013-11-29 16:15:00'
AND wp_reserveit_reservations.start_datetime + INTERVAL 1 HOUR <= '2013-11-29 16:15:00')
OR wp_reserveit_tables.chairs <> wp_reserveit_reservations.table_id
but it gives me SQL error.
So please if you have and idea please write it down.
Thanks
Reservation table will have entry only if there are any reservations. So we can do it simply with NOT IN clause I guess,
SELECT * FROM wp_reserveit_tables WHERE chairs_id NOT IN
(SELECT table_id FROM wp_reserveit_reservations GROUP BY table_id)
In your query you have joined them with chairs column with table_id column. So am not sure which one matches. So please alter the column in Where clause as per your requirement.
You have column name start_datetime in your query and your table structure specifies it to be starttime.
Unless you specify further, this does look like a valid error if it is not a typo.

INSERT statement in joined table

I have 3 table:
tblNames:
| id | firstname | lastname |
+------+---------------+--------------+
| 1 | John | Smith |
tblJosbs (this table accepts multiple checkbox value at the same time):
| id | jobs |
+------+-----------------------+
| 1 | Nurse |
+------+-----------------------+
| 2 | Call Center Agent |
+------+-----------------------+
| 3 | Police |
tblNamesJobs (this table is used to JOIN the other 2 tables):
| id | name_id | jobs_id |
+------+-------------+-------------+
| 1 | 1 | 1 |
+------+-------------+-------------+
| 2 | 1 | 2 |
+------+-------------+-------------+
| 3 | 1 | 3 |
All is fine but can someone show me the INSERT statement for the 3rd table I should use to when I will add new information?
For example add record that John Smith is a Call Center Agent
insert into tblNamesJobs (name_id,jobs_id )
values (
select id from tblNames where
firstname='John'
and lastname='Smith' limit 1
,
select id from tblJosbs where jobs='Call Center Agent' limit 1
);
If you are already depending on tauto increment..you can get the lastinserid, depending on your adapter.
eg. mysql_insert_id
for PDO we can use --PDO::lastInsertId.
so you will have id's of earlier inserted tables, that you can save in the new one.
INSERT INTO tblNamesJobs (name_id, jobs_id) VALUES (XXXX,YYYY)
That is assuming the table's id is auto-incrementing.
It should be noted that both the name_id and jobs_id columns in the "joiner" table should be foreign keys to the respective columns in the other table.
Edit - Valex's answer goes into more detail about what to do if you don't already have the id values.
If possible, I would recommend using some sort of framework that would handle the "joiner" table for you.

Selecting multiple tables MySQL and retrieving different data

I have 4 tables that I need to pull data from. I need to count how many people are signed for a single event and see if a user is applied for an event.
These are my table setups:
TABLE: users
+----+----------+-------+--------+-------+
| id | username | level | class | guild |
+----+----------+-------+--------+-------+
| 1 | example1 | 100 | Hunter | blah |
| 2 | example2 | 105 | Mage | blah2 |
| 3 | example3 | 102 | Healer | blah |
+----+----------+-------+--------+-------+
ID is primary
TABLE: event_randoms
+----+----------+-------+--------+----------+----------+
| id | username | level | class | apped_by | event_id |
+----+----------+-------+--------+----------+----------+
| 1 | random1 | 153 | Hunter | 3 | 3 |
| 2 | random2 | 158 | Healer | 3 | 1 |
| 3 | random3 | 167 | Warrior| 1 | 3 |
+----+----------+-------+--------+----------+----------+
ID is primary
apped_by should be foreign key to users.id
event_id should be foreign key to events.id
TABLE: events
+----+------------+------------+-----------+-----------+-----------+
| id | event_name | event_date | initiator | min_level | max_level |
+----+------------+------------+-----------+-----------+-----------+
| 1 | event1 | date1 | 1 | 100 | 120 |
| 2 | event2 | date2 | 1 | 121 | 135 |
| 3 | event3 | date3 | 1 | 100 | 120 |
| 4 | event4 | date4 | 1 | 150 | 200 |
+----+------------+------------+-----------+-----------+-----------+
ID is primary
TABLE: event_apps
+----+----------+--------------+
| id | event_id | applicant_id |
+----+----------+--------------+
| 1 | 3 | 2 |
| 2 | 4 | 2 |
| 3 | 3 | 1 |
| 4 | 1 | 3 |
+----+----------+--------------+
ID is primary
event_id should be foreign key to events.id
applicant_id should be foreign key to users.id
I will be the first to admit that I am very new to this. I just learned how to use MySQL a few days ago. I can grab stuff from a single table, but I am unsure how to grab from multiple tables.
This is the SQL query I tried
SELECT DD_events.id, event_id, applicant_id, guild, level, class, DD_users.id
FROM DD_events, DD_event_apps, DD_users
WHERE DD_event_apps.event_id = DD_events.id
AND DD_event_apps.applicant_id = DD_users.id
and tried to print_r an array but the array turns up empty.
So a few questions pertain to this:
1: How would I count and display as a number how many people (users and randoms) are signed up for an event?
eg: event 3 should have 4 total (2 users and 2 randoms)
2: How do I see if a particular individual is signed for an event and display text based if they are or not?
eg: user 1 is signed up for event 3 so it would be "Registered" but user 2, who is not signed, would display "Not Registered"
3: I want to display info for who is signed for a particular event in 2 tables, 1 for users and another for randoms.
eg: Event 3 would have 2 users info (username, guild, class, level) under the users table and then 2 random users info (name, class, level, what user applied this person) in the random table.
Any and all help is appreciated even if you can answer 1 part.
I'm thinking this would be your base query:
SELECT
event.id,
app.applicant_id,
usr.guild,
usr.level,
usr.class,
usr.id AS Userid
FROM
DD_events event
JOIN
DD_event_apps app
ON (event.id = app.event_id)
LEFT JOIN
DD_users usr
ON (app.user_id = usr.id)
You can make modifications to this to aggregate it, like so:
SELECT
event.id,
COUNT(app.applicant_id) AS ApplicantCount,
COUNT(DISTINCT usr.guild) AS UniqueGuilds,
COUNT(DISTINCT usr.level) AS UniqueLevels,
COUNT(DISTINCT usr.class) AS UniqueClasses,
COUNT(DISTINCT usr.id) AS UniqueUsers
FROM
DD_events event
JOIN
DD_event_apps app
ON (event.id = app.event_id)
LEFT JOIN
DD_users usr
ON (app.user_id = usr.id)
GROUP BY
event.id
I could write those scripts for you, but I think this provides a good starting point for you to continue from. You'll find that T-SQL is fairly simple when you are trying to get the results you are looking for. Hope this helps!
<?php $query = "SELECT count(*) AS numbuh FROM DD_event_apps WHERE event_id = {$row['id']}";
try
{
// These two statements run the query against your database table.
$stmt = $db->prepare($query);
$stmt->execute();
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("Failed to run query: " . $ex->getMessage());
}
echo($query);
// Finally, we can retrieve all of the found rows into an array using fetchAll
$count = $stmt->fetchAll();
echo($count['numbuh']); ?>

Categories