mysql query two row from two tables - php

I have this Query to call information form two table.
DB::get("SELECT friends. * , (SELECT `login` FROM `users` WHERE `users`.`id` = friends.`user_id`) AS `login` FROM `friends` WHERE `id_user`='" . $this->user['id'] . "' ORDER BY `id` DESC LIMIT ")
So if user is on friends list show username , i would like to get username and avatar. Avatar row is avatar .
I try with this.
DB::get("SELECT friends. * , (SELECT `login`, `*avatar*` FROM `users` WHERE `users`.`id` = friends.`user_id`) AS `login` FROM `friends` WHERE `id_user`='" . $this->user['id'] . "' ORDER BY `id` DESC LIMIT ")
And give me the error
SQLSTATE[21000]: Cardinality violation: 1241 Operand should contain 1 column(s)
where is the mistake?

First of all you should use Prepared Statement and Second, you can't write inline view, which has two columns
SELECT friends. * , (SELECT `login`, `*avatar*` FROM ..
instead you should use JOIN, which might be efficient than current approach and more readable.

You need to use JOIN, e.g.:
SELECT f.*, u.*
FROM friends f JOIN users u ON f.user_id = u.id
WHERE f.id_user = <your_id>
ORDER BY id DESC LIMIT <your_limit>;

Related

SQL select query

I have these tables currently:
assignments(assignment_id, module_id, year, semester, title, number, weighting)
module(module_id, code, name, crn, course_title)
usermodule(usermodule_id, user_id, module_id)
users(user_id, title, first_name, last_name)
I was wondering if anyone could give me guidance on how to get the lecturer name, based on the module_id?
So far I've come up with:
SELECT `first_name` FROM `users` WHERE `assignments.module_id` = '$module_id';
I think I may have to do some form of JOIN query...
try this query
SELECT u.first_name FROM users u
LEFT JOIN usermodule um ON um.user_id = u.user_id
WHERE um.module_id = '$module_id';
How about
SELECT `first_name`
FROM `users` u INNER JOIN
`usermodule` um ON u.user_id = um.user_id
WHERE `um.module_id` = '$module_id';
Try rhis:
SELECT `first_name` FROM
`users` INNER JOIN `usermodule` ON `users.user_id`=`usermodule.user_id`
INNER JOIN `assignments` ON `usermodule.module_id` =`assignments.module_id`
WHERE `assignments.module_id` = '$module_id';
Just try below sql
SELECT `first_name` FROM `users` WHERE user_id = (select user_id from usermodule where module_id = '$module_id' limit 1))
I see poor structuring of your database.
You do not necessarily need a table usermodule to create relationships between the other tables.
If there is a relationship between a user and a module.
make use of a foreign key.
You could have a user_id in the module to link a user to a given module, then have 'module_id' in assignment to link a given assignment to a module, that way in the end, the user, module and assignment are related.
It will then be easy to use JOIN or simple select query

SQL: Check if value is available in tbl1 or tbl2

I want to create a sub-account system (PHP & MYSQL).
I have a user table (users) and a sub users table (sub_users).
How can check if the user is available in the user table, or in the sub users table?
My code:
SELECT DISTINCT *
FROM users
WHERE userid = "steven"
OR WHERE EXISTS (SELECT *
FROM sub_users
WHERE sub_users.userid = "steven");
ERROR: Check your syntax near "steven"
Also tried:
SELECT *
FROM users
LEFT JOIN sub_users
ON sub_users.user_userid = users.userid
WHERE users.userid = 'steven'
OR sub_users.userid = 'steven'
Same error.
In the first place, you only want one where clause. I would also use single quote instead of double quotes:
SELECT DISTINCT *
FROM users
WHERE userid = 'steven' or
EXISTS (SELECT *
FROM sub_users
WHERE sub_users.userid = 'steven'
);
I doubt you need the distinct keyword, if you are fetching all the columns from users.
Your second query looks ok. Are you sure you are not running the first query twice?
EDIT:
I'm trying to figure out what you want to return. The following returns 1 if 'steven' appears in either table and 0 otherwise:
select (case when exists (select 1 from users where users.userid = 'steven') and
exists (select 1 from sub_users where sub_users.userid = 'steven')
then 1
else 0
end);
This method saves on the overhead of a join and will readily take advantage of indexes on users(userid) and sub_users(userid).
You could also use a union:
(SELECT userid FROM users WHERE userid = 'steven')
UNION
(SELECT userid FROM sub_users WHERE userid = 'steven');
select * from
(select * from users) x,
(select * from sub_users) y
where x.user_id = 'steven' or y.user_id = 'steven'
Good luck !!!

Mysql Join without replacing value of original id

I am trying to join my users table with another table using the following query...
SELECT * FROM (`activities`)
JOIN `users` ON `users`.`id` = `activities`.`user`
WHERE `user_subdomain` = 'hi' OR user_subdomain = ''
ORDER BY `activities`.`id` desc
LIMIT 10
Is there any way to do the join so that the id of the user does not replace the id of the activity?
For example, currently if there is an activity with the id of 10 and the user 2 the id will be replaced by the id of the users table and show as 2 after I run the query.
Thanks a lot for the help!
Whenever you are joining tables, you ought to be explicit about the columns you select rather than using SELECT *, and specify column aliases for them when the same column name is used in multiple tables.
SELECT
activities.id,
activities.othercol,
/* Alias to userid */
users.id AS userid,
users.name,
users.anothercolumn
FROM (`activities`)
JOIN `users` ON `users`.`id` = `activities`.`user`
WHERE `user_subdomain` = 'hi' OR user_subdomain = ''
ORDER BY `activities`.`id` desc
LIMIT 10
Though it isn't strictly necessary to prepend the table name to each, unless the column names are the same.
SELECT
activities.id AS activityid,
othercol,
users.id AS userid,
name,
anothercolumn

MySQL how to display data from two tables

I'm trying to display the username of the person who has submitted the most articles but I don't know how to do it using MySQL & PHP, can someone help me?
Here is the MySQL code.
CREATE TABLE users (
user_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
username VARCHAR(255) DEFAULT NULL,
pass CHAR(40) NOT NULL,
PRIMARY KEY (user_id)
);
CREATE TABLE users_articles (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
user_id INT UNSIGNED mNOT NULL,
title TEXT NOT NULL,
acontent LONGTEXT NOT NULL,
PRIMARY KEY (id)
);
Here is the code I have so far.
$mysqli = mysqli_connect("localhost", "root", "", "sitename");
$dbc = mysqli_query($mysqli,"SELECT COUNT(*) as coun, user_id
FROM users_articles
GROUP BY user_id
ORDER BY coun DESC
LIMIT 1");
If you want to get the user's name, you should use the next query:
SELECT users.name, COUNT(users_articles.id) AS coun
FROM users_articles
LEFT JOIN users_articles ON users.id=users_articles.user_id
GROUP BY users_articles.user_id
ORDER BY coun DESC
LIMIT 1
select u.user_id, count(ua.id) as num_articles
from users u
left outer join users_articles ua
on u.user_id = ua.user_id
group by u.user_id
order by num_articles desc
The left outer join (as opposed to an inner join) ensures that all users are represented in the result, no matter if they have a record in users_articles or not.
EDIT: Since you only want the person who has submitted the most articles, you do not necessarily need the left outer join (as long as there is at least one user who has written any articles). For a complete list, it would be useful, however.
Whichever above queries given by geeks u use just DO NOT FORGET TO INCLUDE "username" field in select query as none of them has included the username field
What you want to do is a join.
The SQL query you need is this:
SELECT COUNT(*) as coun, users.user_id, username
FROM users_articles
INNER JOIN users
ON users_articles.user_id = users.user_id
GROUP BY user_id
ORDER BY coun DESC
LIMIT 1
I tested this and it works.
The result table contains the number of articles of the user, its user id and its username.
use like this,
SELECT COUNT(users_articles.*) as coun, users_articles.user_id, users.username
FROM users_articles, users
WHERE users_articles.user_id = users.user_id
GROUP BY users.user_id
ORDER BY coun DESC
SELECT COUNT(*) as coun, user_id, users.username
FROM users_articles, users
WHERE users_articles.user_id = users.user_id
GROUP BY user_id
ORDER BY coun DESC
LIMIT 1

Can I merge two MySQL queries into one?

I had the following code, which uses 2 queries to get the friends list.
<?php
$getFriendStatement = <<<EOS
SELECT DISTINCT u.username
FROM users AS u
INNER JOIN test_friends AS f on u.Id = f.user_id
WHERE f.friend_id = ?
&& f.active=1
EOS;
$getFriendQuery = $mysqli->prepare($getFriendStatement);
$getFriendQuery->bind_param('i', $userID);
$getFriendQuery->execute() or die ($mysqli->error);
$getFriendResult = $getFriendQuery->get_result();
$friendName = "";
while ($getFriendFetch = $getFriendResult->fetch_assoc()) {
$friendName .= $getFriendFetch['username'] . ", ";
}
$getFriendStatement = <<<EOS
SELECT u.username
FROM users AS u
INNER JOIN test_friends AS f ON u.id = f.user_id
WHERE (f.friend_id = ? AND active=1)
OR (f.user_id = ? AND active=1)
EOS;
$getFriendQuery = $mysqli->prepare($getFriendStatement);
$getFriendQuery->bind_param('ii', $userID, $userID);
$getFriendQuery->execute() or die ($mysqli->error);
$getFriendResult = $getFriendQuery->get_result();
while ($getFriendFetch = $getFriendResult->fetch_assoc()) {
$friendName .= $getFriendFetch['username'] . ", ";
}
if (!empty($friendName)){
echo "Your friends: " . $friendName ;
} else {
echo "You do not have any friends yet";
}
?>
Is there a way to execute just 1 query to retrieve all friends?
Schema information: the above relies on two tables, users and test_friends:
CREATE TABLE users (
`id` int(11),
`username` varchar(256)
);
CREATE TABLE test_friends (
`user_id` int(11),
`friend_id` int(11),
`active` tinyint,
FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY (`friend_id`) REFERENCES `users` (`id`)
ON UPDATE CASCADE ON DELETE CASCADE
);
You should be able to do a union to do both queries in one. Your SQL will look like this:
SELECT U.username
FROM users AS U
INNER JOIN test_friends AS F
ON U.Id = F.user_id
WHERE F.friend_id = '{$userID}'
AND F.active = 1
UNION
SELECT u.username
FROM users u
INNER JOIN test_friends f
ON u.id = f.user_id
WHERE ( f.friend_id = '{$userID}'
AND active = 1 )
OR ( f.user_id = '{$userID}'
AND active = 1 )
It will also remove duplicates for you automatically, as if you included DISTINCT on the whole lot. (You do "UNION ALL" if you don't want that.)
Also, if you want to order the results, add "ORDER BY 1 ASC" on the end. You can only use result set column numbers in the ORDER BY clause with unions.
Union queries only work if the number and types of the columns returned in the result set by each sub-query are the same.
Aside: Your first query appears to be a subset of the second query, so you really only need to so the second query. I've left it as is as a demonstration of how to do unions, but you don't really need to in this case.
You can perform a UNION between the two queries. For example:
SELECT username FROM users WHERE username like '%billy%'
UNION
SELECT username FROM users WHERE username like '%bob%'
will return all users with names like billy or bob. Combining your entire two queries above with a UNION should work.
so you want names of $userID's friends AND names of users who have $userID as friend ?
how about
select distinct U.username
from users U
inner join test_friends f
on
(f.user_id = U.id AND f.friend_id={userID}) OR
(f.friend_id=U.id AND f.user_id={userID})
where active=1
As your first query appears to be a subset of your second query, you should only need to execute the second query.
I assume that in the Test_Friends table the user_id field represents the userid of the user and the friend_id field represents the userid of the user's friend.
If this is the case then you can execute the query:
SELECT DISTINCT U.username
FROM Test\_Friends F
INNER JOIN Users U ON F.friend\_id = U.user\_id
WHERE
F.user\_id = '{$userID}' AND
F.active = 1

Categories