mysql join two different tables - php

I have two tables in my MySql database:
user
- sid
- userid
- username
log
- sid
- userid
- login_time
As you can guess, there's a lot more records in log tables than in user table.
I am using php to present these records on my website in a table format as shown below.
no | userid | username | number of login |
1 | inzo | harvey | 233 |
2 | chae | schmidts | 433 |
3 | hibro | swainy | 12 |
To get the number of login for each user, I can send another queries in a for statement. But it's consuming resources and making the server slow in the end.
Can I have this result in one single join query?

Yes you can, you have to use count the logins for each user with a group by
select t1.userid, t1.username, count(t2.sid)
from user t1
left join
log t2
on t1.userid = t2.userid
group by t1.userid, t1.username
The left join ensures you that users without logins will still be returned, wit 0 as count.
Edit
About the question in the comment: if you want to only count the logins with a specific flag value, you can just add where flag = x before the group by; if you want to have a separate count for each value of the flag, you have to add that flag to both group by and select.

I guess best and by that I mean least resource consuming way would be to add "number_of_login" to user table and just increase it every time he/she is logged in, because any other solution will require looping

SELECT TABLE_A.row_id, TABLE_A.category, TABLE_A.val_1, TABLE_B.val_2
FROM TABLE_B
LEFT OUTER JOIN TABLE_A ON TABLE_B.row_id = TABLE_A.row_id
ORDER BY row_id;
If you want all the results, you need an outer join, not an inner one.

select a.sid,a.userid,a.username,COUNT(b.sid) from user a
Left join log b ON b.sid =a.sid group by a.sid

Related

Query to fetch data from two different tables

I have two tables. Table A and B.
I have a log-in form where I will get the username,password, assign, assign2 of the user from table A and fetch data depending on the user's assign1 and assign2 from table B.
How my query would look like?
Looking for answers. Thankyou so much.
Table A -THIS IS THE TABLE FOR LOG-IN FORM
==========================================
username | password | assign1 | assign2 |
------------------------------------------
SANDRA | SANTOS | 1 | 1 | //Values
--------------------------------------------
Table B -
=======================================
name | assign1 | assign 2 |
------------------------------
DADA | 1 | 1 | //this will be displayed
------------------------------
gorg | 2 | 2 |
//this must not be displayed since the user assign1 and assign2 who logged in did not match to this
You are using $sql variable in
$result = $con->query($sql);
It should be $queryagain.
Your question is not clear, but if you want to fetch data from Table B which depends on assign1 and assign2 you can do it like this:
$queryagain = mysqli_query("SELECT * FROM tableB INNER JOIN tableA ON tableB.name=tableA.username WHERE tableA.assign1 = tableB.assign1 AND tableA.assign2 = tableB.assign2");
When you use JOIN it's best practice to JOIN by primary key (id). If tableB.name=tableA.username are not columns with same value you can join by other columns, like assign1, or assign2:
assign1:
$queryagain = mysqli_query("SELECT * FROM tableB INNER JOIN tableA ON tableB.assign1=tableA.assign1 WHERE tableA.assign2 = tableB.assign2");
assign2:
$queryagain = mysqli_query("SELECT * FROM tableB INNER JOIN tableA ON tableB.assign2=tableA.assign2 WHERE tableA.assign1 = tableB.assign1");
Notice: Where clause is not necessay, you can edit WHERE clause depends of the result you want.
I think your are very very new to database programing. First of all I recomend you to read https://www.w3schools.com/sql/sql_join.asp this page and work on examples using try it yourself part.
Join Types:
INNER JOIN: Returns records that have matching values in both tables. That means if assign field is filled in Table A and the value is included in table B then this type of join should match the rows.
LEFT JOIN: Return all records from the left table, and the matched records from the right table. That means all rows in Table A will match either the value is included in table B or not.
RIGHT JOIN: Return all records from the right table, and the matched records from the left table. That means all rows in Table B will match either the value is included in table A or not.
FULL JOIN: Return all records when there is a match in either left or right table. All rows in table A and table B will be included in te result set either they match or not.
Your SQL query may look like:
$sql = "SELECT * FROM table_a a INNER JOIN table_b b on a.assign1 = b.assign1 INNER JOIN table_b b2 on a.assign2 = b2.assign2";
execution part of the sql can be different depending your database engine or other libraries.
I think this thread also helps you: Join two mysql tables with php

MySql CROSS JOIN between two tables and match with another

first of all sorry for my bad english. The scenario i have is the following:
I am developing a notification services that sends notifications messages to many users. I have the following 3 tables on MySql
users(user_id)
notifications(notification_id, notification)
notifications_log(notification_log_id, notification_id, user_id)
Every time that a user read a notification, i insert a record on notifications_log table, ex. John user with user_id = 2 read the notification with notification_id =3: "This is a notification", and then i insert a record on notifications_log with user_id = 2 and notification_id = 3.
There is all ok, but i have to create a query to get all the notifications for all the users that not are inserted on notifications_log. What i have is:
SELECT u.user_id, n.notification_id, n.notification, nl.notification_log_id
FROM users as u
LEFT JOIN notifications_log as nl ON nl.user_id = u.user_id
CROSS JOIN notifications as n
WHERE u.user_id NOT IN (SELECT nl.user_id FROM notifications_log as nl)
AND u.user_id = 1 /* test with user 1 */
If there is no records on notifications_log table of user 1, query results show me
user_id | notification | notification_id | notification_log_id
------------------------------------------------------------------------------
- 1 | Notification_1 | 1 | null
- 1 | Notification_2 | 2 | null
But if i insert at least 1 record on notifications_log for user and notification_2, then i get empty results, and i should get:
user_id | notification | notification_id | notification_log_id
----------------------------------------------------------------------------
- 1 | Notification_1 | 1 | null
It seems that the query joins the notification_log_id to the other record with null notification_log_id...
In short, what I need it is get all the notifications from a especific user that there are not on inserted on the table notifications_log
Thanks in advance!
The query you want is probably this one:
select n.notification_id, u.user_id
from notifications n
cross join users u
left join notifications_log nl
on n.notification_id = nl.notification_id
and nl.user_id = u.user_id
where nl.notification_log_id is null
demo here
This query eliminates your derived table, reducing the execution time, and performs the cross join as early as possible to reduce the total number of rows being operating on.
But i'd suggest rethinking this altogether. Once notifications and users table reaches critical mass this is going to create millions upon millions of rows to filter.
A better idea would be to have a notification_inbox table, as a counterpart to your notifications_log table. When a notification is created, place it in the inbox table for each user. That way you can perform a simple query on a single table to determine unread notifications per user, rather than a potentially horrendously performing cross join.
Alternatively again, a single notification_delivery table, rather than inbox and log tables, which has a 'read' flag. This would also allow targeted notifications, as well as bulk delivery to all users.
It seems like you are on the right track but should just be changing user_id to notification_id in the 2nd to last line:
SELECT u.user_id, n.notification_id, n.notification, nl.notification_log_id
FROM users as u
LEFT JOIN notifications_log as nl ON nl.user_id = u.user_id
CROSS JOIN notifications as n
WHERE n.notification_id NOT IN (SELECT nl.notification_id FROM notifications_log as nl)
AND u.user_id = 1 /* test with user 1 */

Attempting to list data using ID from a particular table

I have one table which stores user info, including the username.
Another table contains a list of user id's and the user id's of those that they have favorited.
I am trying to figure out the query for listing the usernames of those that user id 1 has favorited.
In my query, assuming that I am uid 1, I need the usernames of uid 3 and 5, but instead
in sqlfiddle I am attempting to join them but I keep getting my username, cjaredrun, instead of the matched usernames for each favorite.
You can see what I have been trying here: http://www.sqlfiddle.com/#!2/c5836/1
Any guidance appreciated
You just need a simple join:
SELECT u.username FROM fav_user f
JOIN users u ON u.uid = f.matchuid
WHERE f.uid = 1
ORDER BY datetime
Fiddle here.
Output:
| USERNAME |
|----------|
| jolet |
| jane |

How to find rows in a MySQL database that don't correlate correctly with other rows

I have a table in my MySQL database that, in part, looks like this:
+----+-------+-------+
| id | owner | onwed |
+----+-------+-------+
| 1 | A | B |
| 2 | B | A |
| 3 | C | D |
| 4 | D | C |
| 5 | E | X |
+----+-------+-------+
They important feature here is that all the entries are paired, so that each "owner" is also "owned" by the record they correlate to. A "owns" B, and also B "owns" A. D "owns" C, and also C "owns" D.
However, in row 5,we have a problem. E "owns" X, but there is no entry for X "owning" E.
I need to be able to go through this table, which has thousands of records, and find all instances like row 5, where we have an orphaned record. Where there is no corralating with the "owner" and "owned" fields having a matched opposite. Also, there is no assurance that paired rows will follow each other as they do in my example.
This problem goes way beyond my MySQL abilities. I know how to do a search when I know what the value I'm looking for is. But I don't know how to go through each row one by one, take values out, and then use those values to do another search. I hope someone can help me out and I apologize that I'm so clueless on this matter that I don't have any code to suggest.
I'm not so worried about efficiency, in that this is a check I would only run every now and again when there is reason to suspect a problem. Also, if it helps, I manage my MySQL database from a PHP script, so if there is PHP code that can be leveraged to make the task more manageable, that could also be utilized.
What you need is a join. If you join the table on itself with the owned on owner.
SELECT T1.Id, T1.Owner, T1.Owned, T2.Id, T2.Owner, T2.Owned
FROM tablename T1
LEFT JOIN tablename T2
ON T1.Owned = T2.Owner
WHERE T2.Owned != T1.Owner
OR T2.Id IS NULL
Try to run the query without the WHERE clause to see what this join does. You get both owners and owned on a single row and then you can compare if they match.
You could try a query similar to (not sure about the backquotes of MySQL)
SELECT * FROM `table`
WHERE (`owner`,`owned`)
NOT IN (SELECT `owned`,`owner` FROM `table`);
There are probably cleaner solutions without selfjoins
There are better ways, but this will work:
SELECT
*
FROM
table
WHERE
id NOT IN (
SELECT
id
FROM
table s1
WHERE
s1.owner = (
SELECT
onwed
FROM
table s2
WHERE
s2.onwed = s1.owner
)
);
Its easy:
select t1.id from tableName as t1 left join tableName as t2
on t1.owner = t2.owned and t1.owned = t2.owner
where t2.id is null
select
*
from
mytable
where id not in (
select
m1.id
from
mytable m1,
mytable m2
where
m1.owner=m2.owned
)
You can try this- demo below :
http://sqlfiddle.com/#!2/0db47/7
SELECT a.id, a.owner, a.onwed
FROM TableName a
LEFT JOIN TableName b
ON (a.Owner = b.Owner AND a.Onwed = b.OnWed) OR
(a.Owner = b.OnWed AND a.Onwed = b.Owner)
GROUP BY a.id, a.owner, a.onwed
HAVING COUNT(*) = 1
SQLFiddle Demo

Nested or Joins query for MySQL using PHP

I have many a times tried using nested query for MySQL in PHP, but it does not work. Is it not possible to do nested/Joins queries?
Just a Scenario:
I have two tables one table with user id and the other with data. User logins and with sessions I have to cross check two different tables with user id (user and data). Is it not possible to nest/join these two tables to write a single query statement.
In short is nesting or joining two or more tables permitted in PHP coding?
YES, it is possible to join two or more tables in MySQL (and therefore, also when using PHP).
You need to post your table schema, if you want us to show a relevant join query. You could, however, try something like:
SELECT * FROM user AS t1
CROSS JOIN data AS t2
ON t1.userid=t2.userid
WHERE t1.userid='154'
(This query presumes that there always will be one row with the userid in both tables. You should use LEFT JOIN instead of CROSS JOIN to return a row even if there is no row in data for the userid. 154 is just an example userid.)
Have a look at http://dev.mysql.com/doc/refman/5.5/en/join.html for information on the JOIN syntax.
users
| user_id | username | password | enabled |
|---------|----------|----------|---------|
| 1 | john | sgsd2gg | 1 |
| 2 | jane | sdshdhd | 0 |
users_data
|udata_id| user_id | some_column |
|--------|---------|-------------------|
| 1 | 1 | Some title |
| 2 | 2 | another title |
Since you haven't posted your table schema, I can't give you an exact solution. But supposing you have a users table and a users_data table, where users_data are owned by a user. You can do a join on the table to retrieve all the data.
SELECT * -- Don't select all fields unless you need it
FROM users U LEFT JOIN users_data UD ON U.user_id = UD.user_id
WHERE U.user_id = 1
This would pull all the records for user with an ID of 1. This is a very simplistic join, but it should give you an idea.
Here's an example that visually describes the different options you can use : SQL Join Differences

Categories