MYSQL Select from tables based on multiple rows - php

I have a table called user_meta. In that table I have the following columns: ID, userID, meta_key, meta_value
I have another table called users, the only important column there is ID, which I want to compare to the user_meta table rows.
The users table looks like:
ID | email | etc...
1 | email#test.com |
5 | testa#a.com |
6 | .... |
7 | .... |
So say I have a table (user_meta) that looks like:
ID | userID | meta_key | meta_value
2 | 1 | companyID | 2
3 | 1 | user_type | staff
4 | 5 | companyID | 2
5 | 5 | user_type | staff
6 | 6 | companyID | 4
7 | 6 | user_type | customer
I want to retrieve a single row for each userID, but only if the company ID and user_type are correct.
I want to retrieve all users that have the same companyID that I would send in the query, so let's say $companyID=2, and then all users that have the user_type='staff'.
So user_meta.userID must equal users.ID, and user_meta.companyID must equal 2, and user_meta.user_type must equal 'staff'.
I want a list of all users that match these criteria.
A result would be userID 1 & 5 are returned. They both have companyID = 2, and both have user_type = staff

You need to join with user_meta once for each attribute you want to match.
SELECT u.*
FROM users AS u
JOIN user_meta AS m1 ON u.id = m1.userID
JOIN user_meta AS m2 ON u.id = m2.userID
WHERE m1.meta_key = 'companyID' AND m1.meta_value = :companyID
AND m2.meta_key = 'user_type' AND m2.meta_value = 'staff'

Not very sure about your question. I'm assuming this is what you may want:
select * from Users where ID in (
select userID from user_meta where (meta_key = 'companyID' and meta_value = 2) or (meta_key = 'user_type' and meta_value = 'staff')
);

SELECT `users`.`id`,
`Company`.`meta_value`,
`UserType`.`meta_value`
FROM `users`
JOIN `user_meta` `Company`
ON `Company`.`userid` = `users`.`id`
JOIN `user_meta` `UserType`
ON `UserType`.`userid` = `users`.`id`
WHERE `UserType`.`meta_value` = 'staff'
AND `Company`.`meta_value` = 2
https://gyazo.com/de8d9124418f65b993d708c80c309325

Related

How do i display friends of a user in mysql?

I am creating a friend list module.
I have 2 tables: users table and friends table. I want the program to display the friends of a user without displaying the user as one of his/her own friend.
My table looks like
Users table
---------- ---------- ---------
user_id | username | password
-------------------------------
1 | elexis | *******
-------------------------------
2 | rooney | *******
-------------------------------
3 | wayne | *******
-------------------------------
4 | June | *******
-------------------------------
Friends table
---------- ----------
user_id | friend_id
---------------------
1 | 3
-----------
2 | 1
-----------
2 | 4
-----------
1 | 2
Expected output of user_id 1 (who is elexis) should be
User_id friend_id Username
1 3 Wayne
2 1 Rooney
My code is thus:
SELECT t1.user_id,t1.friend_id, t2.username
FROM friends AS t1
LEFT JOIN users AS t2
ON (t1.user_id = t2.user_id)
OR (t1.friend_id = t2.user_id)
WHERE t1.user_id = 1
The output I'm getting is:
User_id Friend_id Username
1 5. Elexis
1 1 Elexis
What am I getting wrong?
Join Users to a query that contains distinct pairs of user with id = 1 and each pair:
SELECT f.*, u.username
FROM Users u
INNER JOIN (
SELECT user_id, friend_id FROM Friends WHERE user_id = 1
UNION
SELECT friend_id, user_id FROM Friends WHERE friend_id = 1
) f ON f.friend_id = u.user_id;
Or, if you want to pass the user parameter only once:
SELECT f.*, u.username
FROM Users u
INNER JOIN (
SELECT user_id, friend_id FROM Friends
UNION
SELECT friend_id, user_id FROM Friends
) f ON f.friend_id = u.user_id
WHERE f.user_id = 1
See the demo.
You need to join on Friend_id and select user_id from Friends table.
SELECT f.user_id,f.friend_id,u.username
FROM friends f JOIN users u
ON f.user_id=f.friend_id
This gives you output:
user_id | friend_id | username
1 | 3 | Wayne
2 | 1 | Elexis
You can union two qieroes which give you the result
CREATE TABLE friend
(`user_id` int, `friend_id` int)
;
INSERT INTO friend
(`user_id`, `friend_id`)
VALUES
(1, 3),
(2, 1),
(2, 4),
(1, 2)
;
CREATE TABLE users
(`user_id` int, `username` varchar(6), `password` varchar(7))
;
INSERT INTO users
(`user_id`, `username`, `password`)
VALUES
(1, 'elexis', '*******'),
(2, 'rooney', '*******'),
(3, 'wayne', '*******'),
(4, 'June', '*******')
;
SELECT f.*, u. username FROM friend f JOIN users u ON f.friend_id = u.user_id WHERE f.user_id = 1 AND f.`friend_id` NOT IN (SELECT user_id FROM friend WHERE friend_id = 1)
UNION
SELECT f.*, u.username FROM friend f JOIN users u ON f.user_id = u.user_id WHERE friend_id = 1
user_id | friend_id | username
------: | --------: | :-------
1 | 3 | wayne
2 | 1 | rooney
db<>fiddle here

Need assistance with this SQL query

This is an example of my table. I have multiple entries on multiple rows for a given post_id (this is metadata for posts).
post_id | meta_key | meta_value
________ __________ ___________
| |
1 | _theDate | 2016-03-31
1 | _email | the#email.com
2 | _theDate | 2016-01-06
2 | _email | the#email.com
3 | _theDate | 2017-02-14
3 | _email | other#user.net
4 | _theDate | 2016-10-01
4 | _email | the#email.com
5 | _theDate | 2016-09-25
5 | _email | other#user.net
6 | _theDate | 2015-11-19
6 | _email | other#user.net
What I am trying to accomplish:
I would like to find all instances of a post with the email address the#email.com and the year "2016" in the metadata, and then count those individual posts to find out how many posts were written by the user the#email.com during the year "2016".
For the moment I have managed to find only the instances of the email address using
SELECT DISTINCT post_id
FROM metatable
WHERE meta_value LIKE '%the#email.com%'
This counts the total posts for that user but not only the ones written in 2016.
Here is one method that uses two levels of aggregation :
SELECT COUNT(*)
FROM (SELECT post_id
FROM metatable
WHERE (meta_key = '_email' AND meta_value = 'the#email.com') OR
(meta_key = '_theDate' AND LEFT(meta_value, 4) = '2016')
GROUP BY post_id
HAVING COUNT(DISTINCT meta_key) = 2
) p;
Edit : missing a quote
Here you go:
SELECT t.post_id -- Replace with `SELECT count(*)` to just have the total
FROM table t
WHERE t.meta_key = '_email' AND t.meta_value = 'the#email.com' AND
EXISTS (
SELECT 1
FROM table
WHERE post_id = t.post_id AND YEAR(meta_value) = 2016
meta_key = '_theDate' AND meta_value = xxx
);
SELECT
COUNT(*)
FROM
metatable m1
INNER JOIN metatable m2 ON m2.post_id = m1.post_id
WHERE
AND m1.meta_key = _theDate
AND m1.meta_value LIKE '2016%'
AND m2.meta_key = _email
AND m2.meta_value = 'the#email.com'
Start by joining the table with itself, in order to get a 'id-user-date' structured table:
SELECT email.post_id, email.meta_value as mail, date.meta_value as date from metatable as email
inner join metatable as dateTable
on email.post_id = dateTable.post_id
and email.meta_key = '_email'
and dateTable.meta_key = '_theDate'
And on that you can do what you want:
SELECT count(*) from metatable as email
inner join metatable as dateTable
on email.post_id = dateTable.post_id
and email.meta_key = '_email'
and dateTable.meta_key = '_theDate'
where
email.meta_value = 'the#email.com'
and date.meta_value like '2016%';
Considering that you would like count all where the meta_key is "_theDate" the Select will:
SELECT COUNT(1) FROM table WHERE YEAR(aux_meta_value) = "2016" AND meta_key = '_theDate'

How do I make this select query?

I want to create a SELECT query in mysql.
There are two tables, users and image_info, and need to select following columns.
user table : user_id, username, dob
image_info : image, image_path
When selecting image. I need to get only primary image from image_info table. In image_info table there is a column like:
image_type ENUM('primary', 'gallery') DEFAULT NULL,
This is how I tried it..
$q = "SELECT u.user_id, u.username, u.dob, i.image, i.image_path
FROM users u
INNER JOIN image_info i ON i.user_id = u.user_id
WHERE u.sex = 'Male'
ORDER BY u.date_registered DESC LIMIT 6";
But it doesn't work properly to get my expected output.
UPDATE:
my table outputs..
mysql> select user_id, username, sex from users;
+---------+-------------+--------+
| user_id | username | sex |
+---------+-------------+--------+
| 1 | thara1234 | Male |
| 2 | root234 | Male |
| 3 | kamal123 | Female |
| 4 | Nilantha | Male |
| 5 | Ruwan324324 | Male |
+---------+-------------+--------+
5 rows in set (0.00 sec)
mysql> select user_id, image, image_type from image_info;
+---------+----------------------------+------------+
| user_id | image | image_type |
+---------+----------------------------+------------+
| 2 | 2_root234_1433564588.jpg | primary |
| 1 | 1_thara1234_1433555104.jpg | primary |
| 1 | 1_thara1234_1433556481.jpg | gallery |
| 4 | 4_Nilantha_1433573768.jpg | primary |
+---------+----------------------------+------------+
4 rows in set (0.03 sec)
Thank you.
I think, query would be :-
SELECT User.user_id, User.username, User.dob, Image.image, Image.image_path
FROM
users User LEFT JOIN image_info Image
ON User.user_id = Image.user_id AND Image.image_type = 'PRIMARY'
WHERE User.sex= 'Male'
ORDER BY User.date_registered DESC LIMIT 6
As you said you need the user either he has an image or not you should use left join in your query:
SELECT u.user_id, u.username, u.dob, i.image, i.image_path
FROM users u
LEFT JOIN image_info i ON i.user_id = u.user_id
WHERE u.sex = 'Male' and (i.image_type = 'primary' or i.image_type is null)
ORDER BY u.date_registered DESC LIMIT 6;
See here for more information.

Check if row has specific childs on join

I want to make a SQL to get the user which name is Mark and are the author of the posts with ids 1 and 3.
NOTE: It is unknown how many posts I need to check for. So it might need to generate that part of the SQL query using PHP.
How can that be done?
Users Table:
+----+----------+
| id | name |
+----+----------+
| 1 | Mark |
| 2 | John Doe |
+----+----------+
Posts Table
+----+-------------+-------------+
| id | text | author_id |
+----+-------------+-------------+
| 1 | First Post | 1 |
| 2 | Second Post | 2 |
| 3 | Last Post | 1 |
+----+-------------+-------------+
This is just a sample case of use, not real data.
NOTE: I know how to check if user is author on one post, but not multiple in the same row. So basicly that is what I need help with, I guess it must be a left join.
For making the check for the user named Mark and check if he is author for post id 1 I do the following:
SELECT users.*
FROM users
INNER JOIN posts
ON users.id = posts.author_id
WHERE
users.name = 'Mark'
&&
posts.author_id` = 1
I just selected the id from users. If you need more columns then just add it to the select and the group by clause.
SELECT users.id
FROM users
INNER JOIN posts ON users.id = posts.author_id
WHERE users.name = 'Mark'
AND posts.author_id in (1,3)
GROUP BY users.id
HAVING count(distinct posts.author_id) = 2
Use a sub-query to find only users with both 1 and 3:
SELECT users.*
FROM users
WHERE users.name = 'Mark'
and 2 = (select count(distinct posts.id)
where users.id = posts.author_id
and posts.id IN (1,3))
SELECT users.name, posts.posts, posts.authorid
FROM users INNER JOIN posts ON users.id = posts.authorid where posts.authorid = 1
You need to use HAVING clause to achieve desired outcome:
SELECT users.name
FROM users
INNER JOIN posts
on users.id = posts.author_id
WHERE users.name = 'Mark'
GROUP BY users.name
HAVING COUNT(posts.author_id) > 1

SELECT multiple table

i need some help here,
table "friends"
+------+-------------+-----------+
id | friend_id | user_id |
+------+-------------+-----------+
1 | 1222 | 99999 |
+------+-------------+-----------+
2 | 48989 | 1492 |
+------+-------------+-----------+
table "users"
+------+-------------+---------------+
id | user_name | user_image |
+------+-------------+---------------+
99999 | Mark | img/abc.jpg |
+------+-------------+---------------+
1222 | Tom | img/xyz.jpg |
+------+-------------+---------------+
etc. | etc. | etc.. |
+------+-------------+---------------+
i want SELECT table friends and make WHERE statement :
etc : ... WHERE user_id=$_SESSION[user_id] ...
and will display data from table users
ok , let say :
my current id is 99999 so in table friends is match only 1222 , so this will display all data(image,etc..) from id 1222(Tom) from table users.
So my question here is how i need to write this code for generate users data ?
*i try to use UNION and LEFT JOIN..but no luck..still newbie..
$user_id = intval($_SESSION['user_id']);
$friends_of_user = mysql_query('
SELECT
f.*, u.*
FROM
friends f
LEFT JOIN
users u
ON
u.id = f.friend_id
WHERE
f.user_id = '.$user_id);
and to exclude all users which doesn't have profiles in users table, just change LEFT JOIN to JOIN
I'd use the following code:
$user_id = mysql_real_escape_string($_SESSION['user_id']);
$sql = "SELECT f.*
FROM users u
INNER JOIN friends f ON (u.user_id = f.friend_id)
WHERE u.user_id = '$user_id' ";

Categories