How to not exist on another table - php

How to not exist on another table on this two table?
Users table
User_relationships table
and this is my current query
"SELECT * FROM `users`
WHERE CONCAT(first_name, " ", last_name) LIKE '%' . $name . '%'
AND (`role_id` = 6 OR `role_id` = 4)
ORDER BY `first_name` asc limit 15"
and I want to add on query where guardian_id(user_id) not exist on the user_relationships table
UPDATE 1
select * from `users`
where not exists
(select 1 from `user_relationships`
inner join `users` on `user_relationships`.`guardian_id` = `users`.`id`
where `user_relationships`.`student_id` = 422)
I tried this and still returns me zero result.
I only have var name = ? and student_id = ?

try to use "NOT IN" query function with 'DISTINCT'.
following may help you.
select * from users where CONCAT(first_name, " ", last_name) LIKE '%' . $name . '%' and (role_id= 6 or role_id= 4) and (id NOT IN (select DISTINCT guardian_id from User_relationships where student_id = $student_id)) order by first_name ASC limit 15
Let me know if you still need some changes.

Related

Display Alphabetical order a list of name and surname

I need to display in alphabetical order a list of name and surname (order by surname).
The problem is I can't do a ORDER BY in SQL query because I retrieve my users ID in one table and retrieve the informations in another table.
My PHP code:
$sql = "select id FROM $table_name";
$result = $wpdb->get_results($sql);
foreach ($result as $record) {
$id = $record->id;
$sql2 = "select field_name, field_val FROM $table_name2 where sub_id = $id";
$result2 = $wpdb->get_results($sql2);
foreach ($result2 as $record2) {
if($record2->field_name == "Nom :") {
$surname = ucfirst(stripslashes($record2->field_val));
}
if($record2->field_name == "Prénom :") {
$name = ucfirst(stripslashes($record2->field_val));
}
}
echo $name . " " . $surname . "<br/>";
}
Here the architecture of the second table:
f_id sub_id field_name field_val
127 19 Prénom : Philippe
128 19 Nom : Nailloux
129 20 Prénom : John
130 20 Nom : Drumond
Have you an idea how I can display my list ordered by surname alphabetically?
Thanks.
You can do the trick by using this SQL query :
SELECT t1.id AS user_id,
t2.field_val AS surname,
t3.field_val AS name
FROM $table_name t1
JOIN $table_name2 AS t2
ON ( t2.sub_id = t1.id
AND t2.field_name = 'Nom :' )
JOIN $table_name2 AS t3
ON ( t3.sub_id = t1.id
AND t3.field_name = 'Prénom :' )
ORDER BY t2.field_val
The query will return all the infos needed (user_id, surname and name) ordered by surname.
Use subqueries!
In your example, let's say you have 100 users.
In first query you get your users ids, then for each user you query database for one's data. That's 101 queries for a simple operation! What if you have 10 visits per seconds? That's more than 1000 queries.
There are many strategies (subquery, join, two queries with in () in second one) but in this case consider that:
SELECT
field_name, field_val
FROM
$table_name2
WHERE
sub_id IN(
SELECT
id
FROM
$table_name
) as sq1
ORDER BY field_val ASC;
Also consider using PHP PDO, or at least proper escaping of data you put in queries.

Return row if non existent in other table

I have 2 tables
members
=======
id
f_name // get these values.
l_name
email
friends
=======
to
from
The users's I'd is the value $member_id, if it is present in "to" or "from" I want it to not return the other value of that row, so only non-friends are shown.
Im creating a page to allow members to search through the database to add their friends by email, or name.
I'd like to return all rows from members where there is no record of the userid in either the "to" or "from" columns of the friends table.
I know how to do most basic mysql but joins are an issue for me, i don't really understand how to write them, if anyone can help me out and maybe even explain it a bit that would be great!
My query now:
$query = "SELECT * FROM members WHERE f_name LIKE '%" . $word . "%' OR l_name LIKE '%" . $word . "%' OR mc_name LIKE '%" . $word . "%' OR email LIKE '%" . $word . "%' LIMIT 10";
//Where $word is the search term.
Modified Query
SELECT * FROM members WHERE id NOT IN (SELECT to FROM friends WHERE frm=$member_id) AND $member_id NOT IN (SELECT frm FROM friends WHERE to=$member_id) AND f_name LIKE '%" . $word . "%' OR l_name LIKE '%" . $word . "%' OR mc_name LIKE '%" . $word . "%' OR email LIKE '%" . $word . "%' LIMIT 10
Edited
So, suppose a user with id 3:
SELECT *
FROM members
WHERE id <> 3
AND id NOT IN (SELECT to FROM friends WHERE from = 3)
AND id NOT IN (SELECT from FROM friends WHERE to = 3)
[Other conditions....];
OR
SELECT *
FROM members
LEFT JOIN friends
ON (members.id = friends.to
OR members.id = friends.from)
AND (members.to = 3
OR members.from = 3)
WHERE friends.to IS NULL
AND id <> 3
[Other conditions....];
Maybe consider change the name of your "from" and "to" columns, to avoid confusion, because FROM and TO are reserved words.
Also, you can use the reserved word EXPLAIN , before the query, to see the difference of the number of rows being fetched.
You might be able to do that using an LEFT Join, which will return all rows from members even if there's no corresponding row on the friend's table.
Something like this:
SELECT a.*, f.* FROM members m LEFT JOIN friends f
A great article to understand the many joins there are is this one.

Mysql Query Selecting Results With A Distinct Column Value

I have a table that displays books. However I would like only only 1 book to be shown per unique email address (strContactEmail). I tried the below query, it didn't work. Any help greatly appreciated.`
$sql = "SELECT lngbookid, strTitle, strAuthor, strcoursecode, strISBN, ".
" strcontactname, DISTINCT(strContactEmail) AS strContactEmail, ".
" curPrice, ysnsalerent, dtmpostdate, memcomments, school, ".
" ASIN, BookIMG, ISBN10, ISBN13, Updated, ".
" datetime, user_ip, NoOtherBooks ".
" FROM tblbooks ".
" WHERE strcoursecode LIKE '%$search%' ".
" ORDER BY datetime DESC LIMIT 50";
Try a GROUP BY statement:
http://www.w3schools.com/sql/sql_groupby.asp
The easiest way:
SELECT max(lngbookid) as lngbookid,
max(strtitle) as strtitle,
max(strauthor) as strauthor,
max(strcoursecode) as strcoursecode,
max(strisbn) as strisbn,
max(strcontactname) as strcontactname,
strcontactemail,
max(curprice) as curprice,
max(ysnsalerent) as ysnsalerent,
max(dtmpostdate) as dtmpostdate,
max(memcomments) as memcomments,
max(school) as school,
max(asin) as asin,
max(bookimg) as bookimg,
max(isbn10) as isbn10,
max(isbn13) as isbn13,
max(updated) as updated,
max(datetime) as datetime,
max(user_ip) as user_ip,
max(nootherbooks) as nootherbooks
FROM tblbooks
WHERE strcoursecode LIKE '%$search%'
GROUP BY strcontactemail
ORDER BY datetime DESC
LIMIT 50
EDIT
Well, the above was actually too "dummy". Better way to do this is (providing that column "lngbookid" is a primary key):
SELECT a.lngbookid,
a.strtitle,
a.strauthor,
a.strcoursecode,
a.strisbn,
a.strcontactname,
a.strcontactemail,
a.ontactemail,
a.curprice,
a.ysnsalerent,
a.dtmpostdate,
a.memcomments,
a.school,
a.asin,
a.bookimg,
a.isbn10,
a.isbn13,
a.updated,
a.datetime,
a.user_ip,
a.nootherbooks
FROM tblbooks AS a
JOIN (SELECT strcontactemail,
Max(lngbookid) AS lngbookid
FROM tblbooks
GROUP BY strcontactemail) AS b
ON ( a.strcontactemail = b.strcontactemail
AND a.lngbookid = b.lngbookid )

How to combine all these MySQL queries into one?

I have a lot of articles tagged with the tag "dog". I have a new tag now called "cat". I want to add the tag "cat" to all articles that already have the tag "dog". A few articles have both tags. I don't want to retag these with "cats".
In other words, if an article has the tag "dog" and doesn't yet have the tag "cat" I want to add the tag "cat" to it. Here is the script I wrote:
<?php
# Get "cat" tag id
$sql = "SELECT `id`
FROM tags
WHERE name = 'cat'
LIMIT 1";
$cat_tag = mysql_fetch_assoc(mysql_query($sql));
# Get "dog" tag id
$sql = "SELECT `id`
FROM tags
WHERE name = 'dog'
LIMIT 1";
$dog_tag = mysql_fetch_assoc(mysql_query($sql));
######################################
# Get all nodes tagged with "dog"
$sql = "SELECT `node_id`
FROM node_tags
WHERE `tag_id` = '" . $dog['id'] . "'";
$query = mysql_query($sql);
while($row = mysql_fetch_assoc($query)) {
# Check to see if current node has "cat" tag already
$sql = "SELECT COUNT(*)
FROM node_tags
WHERE `node_id` = '" . $row['node_id'] . "'
AND `tag_id` = '" . $cat['id'] . "'";
$check_already_exists = mysql_fetch_assoc(mysql_query($sql));
# If node doesn't already have "cat" tag, then add it
if($check_already_exists == '0') {
$sql = "INSERT INTO `node_tags`(node_id, tag_id)
VALUES('" . $row['node_id'] . "', '" . $cat['id'] . "')";
mysql_query($sql);
}
}
?>
I want to be able to run this directly from my MySQL manager tool. So it can't have any PHP but should be one large SQL query. How to do this?
The following query gets all "dogs" that have no cat id. It then inserts them into the table:
insert into node_tags(node_id, tag_id)
SELECT id, $cat['id']
FROM tags t join
node_tags nt
on t.node_id = nt.node_id
WHERE t.name = 'dog'
group by id
having max(case when tag_id = $cat['id'] then 1 else 0 end) = 0
You can't do this in one query, because you would need to insert data that depends on selecting data from the same table. The closest you can get is something like this, assuming you have a unique key defined on (node_id,tag_id):
CREATE TEMPORARY TABLE `tmp` (`node_id` TEXT, `tag_id` TEXT); # Choose better column types if possible
INSERT INTO `tmp` SELECT `node_id`, `tag_id` FROM `node_tags`;
SET #id_cat = (SELECT `id` FROM `tags` WHERE `name`='cat'),
#id_dog = (SELECT `id` FROM `tags` WHERE `name`='dog');
INSERT IGNORE INTO `node_tags` (`node_id`, `tag_id`)
SELECT `node_id`, #id_cat FROM `tmp` WHERE `tag_id`=#id_dog
UNION
SELECT `node_id`, #id_dog FROM `tmp` WHERE `tag_id`=#id_cat;
DROP TABLE `tmp`;
You can paste this into your MySQL manager tool and it should work.
You can make a insert based in a select clause:
INSERT INTO node_tags (node_id, tag_id)
SELECT node_id, (SELECT MAX(id) FROM tags WHERE name = 'cat')
FROM node_tags
WHERE tag_id = (SELECT MAX(id) FORM tags WHERE name = 'dog')
Make a backup before you try something like that ;)
Try this query. I havn't tested this. But I think this will work.
INSERT into node_tags(node_id, tag_id)
( SELECT node_id, tag_id
FROM node_tags nt , tags t
where t.id = nt.tag_id AND t.name = 'dog'
AND nt.node_id NOT IN (SELECT t1.id FROM node_tags nt1, tags t1
where nt1.node_id = nt.node_id AND t1.id = nt1.tag_id AND t1.name = 'cat')
)
First change your table and make (node_id and tag_id) together UNIQUE, because that's what it seems that you need.
ALTER TABLE `node_tags` ADD UNIQUE (`node_id`,`tag_id`);
this is your query:
$sql = "INSERT IGNORE INTO `node_tags`
SELECT (SELECT `node_id` FROM node_tags WHERE EXISTS (SELECT tags.* FROM tags WHERE node_tags.`tag_id` = tags.`id` AND tags.name = 'dog') LIMIT 1),
(SELECT `id` FROM tags WHERE name = 'cat' LIMIT 1)";

MySQL where column = 'x, y, z'

Here's my situation: I need to select all the messages where user_id = x OR y OR z.
I have an array in PHP:
users = ('1', '2', '3')
is there anyway to select all the messages where user_id = one of those values without having a massive query of:
user_id = '1' OR user_id = '2' OR user_id = '3?'
(I need to receive the messages of 100+ people so it would be inefficient)
Thanks
Use an IN clause.
SELECT *
FROM YourTable
WHERE user_id IN ('1','2','3')
Yes! You can use the IN operator:
user_id IN ('1', '2', '3')
If your array will always be safe and contain elements, you can do:
"user_id IN ('" . implode("', '", $users) . "')"
in PHP, too.
This is easy to do :
$query = "SELECT * FROM table_name WHERE user_id IN('1','2','3')";
Since your value is in array you can use:
$users = array('1', '2', '3');
$user_id = "'" . implode("', '", $users ) . "'";
$query = "SELECT * FROM table_name WHERE user_id IN($user_id)";
Hope this helps.
Probably you don't like IN keyword. Instead, you can use a regular expression like this:
select * from your_table where user_id regexp '1|2|3'
user_id >= 1 AND <= 3
Is one alternative.
before strings ids are:
$query = "SELECT * FROM table_name WHERE user_id IN('1','2','3')";
preformance int for ids:
$query = "SELECT * FROM table_name WHERE user_id IN(1,2,3)";

Categories