How can I check an other table before updating? - php

I have these two tables:
// users
+----+-------+-----------------------+--------+
| id | name | email | active |
+----+-------+-----------------------+--------+
| 1 | peter | peter12#hotmail.com | NULL |
| 2 | jack | most_wanted#gmail.com | NULL |
| 3 | john | john_20016#yahoo.com | NULL |
+----+-------+-----------------------+--------+
// activate
+----+---------+---------------------+
| id | post_id | random_string |
+----+---------+---------------------+
| 1 | 2 | fewklw23523kf |
+----+---------+---------------------+
Also I have an URL like this:
http://example.com/activate.php?str=fewklw23523kf
All I'm trying to do:
Comparing GET['str'] with random_string column from activate table
Checking active column for NULL where id = post_id.
And then (if there is matched row) set 1 the active column from users table. How can I do that?
$str = $_GET['str'];
$stm = $db_con->prepare( "UPDATE users SET active = 1
WHERE ( SELECT 1 FROM activate WHERE random_string = ? ) t AND
( SELECT 1 FROM users WHERE t.post_id = id AND
active IS NULL ) ");
$stmt->execute(array($str));
My query doesn't work as expected.

You can use join
UPDATE users
INNER JOIN activate on activate.post_id = user.id
SET active = 1
WHERE activate.random_string = ?
AND user.active IS NULL;

try to change
( SELECT 1 FROM users WHERE t.post_id = id AND active IS NULL )
to this
( SELECT 1 FROM users, activate as t WHERE t.post_id = id AND active IS NULL)

I do believe this one will do the trick
UPDATE users, activate SET active = 1
WHERE users.id = post_id and active is null and random_string=?

Related

How to display name instead of id if records are in one table?

I am using CodeIgniter. I have an employee table and records are
id |firstname | lastname | mobileno | created_by
2 |mnb | nbgfv | 1452145625 | 1
3 |jhg | uhgf | 1452365478 | 2
4 |poi | ijuy | 1458745632 | 2
5 |tgf | tgfd | 1458745254 | 2
6 |wer | qwes | 1523654512 | 2
Now My issue is in the column created_by. When I am displaying the record of any id value then I am getting the output like
id |firstname | lastname | mobileno | created_by
3 |jhg | uhgf | 1452365478 | 2
But my expected output
id |firstname | lastname | mobileno | created_by
3 |jhg | uhgf | 1452365478 | mnb nbgfv
I have to display the name of created_by
I tried only this query.
$get_single_emp_record = array('id' => 3);
$this->db->where($get_single_emp_record);
$query = $this->db->get('tbl_employee');
$result = $query->row();
if($result)
{
return $result;
}
else
{
return 0;
}
I have a hint (maybe this can give solution in your problem).
Try query like this :
SELECT
t1.id , t1.firstname , t1.lastname ,t1.mobileno,
CONCAT(t2.firstname ," ",t2.lastname ) AS createby
FROM tbl_employee AS t1
JOIN tbl_employee AS t2 ON t2.id = t1.created_by
WHERE t1.id = '3'
With above query you no need create temporary table or other additional tables.
I Tested it. >>>
http://sqlfiddle.com/#!9/e693cf/2/0
Thanks
you will have to create another table maybe tbl_creator which will have the id, creator_name then in your query you will perform a Join operation

How to update data as null in mysql using php loop?

I have a table named users with a column called user_subs. It looks like this.
In user_subs I have stored the specific users session username. Lets say this specific users name is James.
Now how would I loop through a specific user_subs looking for "James" and remove him from that specific user_subs without removing all the other names.
This is what I have so far and the only problem is, its deleting all the usernames in user_subs instead of just "James".
if(isset($_GET['p_id'])) {
$the_post_id = $_GET['p_id'];
$the_post_author = $_GET['author'];
}
if(isset($_POST['delete_sub'])) {
$username = $_SESSION['username'];
$query = "SELECT user_subs FROM users WHERE username = '{$username}' ";
$select_users_by_id = mysqli_query($connection, $query);
while ($row = mysqli_fetch_array($select_users_by_id)) {
$user_subs = explode(',', $row['user_subs']);
foreach($user_subs as $out) {
$query = "UPDATE users SET user_subs = null WHERE username = '{$the_post_author}' ";
$unsubscribe_user = mysqli_query($connection, $query);
echo "Unsubscribed";
}
}
}
THIS IS JUST IN TEST, PREPARED STATEMENTS WILL BE USED BEFORE GOING LIVE
Thank you for your time.
I second the other user's comment about moving this column to a different table. In the meanwhile, if you want to achieve what you are asking for, you can try removing the user name from the column value and update it with the remaining text.
if(isset($_POST['delete_sub'])) {
$username = $_SESSION['username'];
$query = "SELECT user_subs FROM users WHERE username = '{$username}' ";
$select_users_by_id = mysqli_query($connection, $query);
while ($row = mysqli_fetch_array($select_users_by_id)) {
$user_subs = str_replace($username . ',', '', $row['user_subs']);
$query = "UPDATE users SET user_subs = '{$user_subs}' WHERE username = '{$the_post_author}' ";
$unsubscribe_user = mysqli_query($connection, $query);
echo "Unsubscribed";
}
}
OPTION-2
$user_subs = explode(',', $row['user_subs']);
$user_subs_new = [];
foreach($user_subs as $out) {
if ($out !== $username) {
$user_subs_new[] = $out;
}
}
$user_subs = implode(',',user_subs_new);
$query = "UPDATE users SET user_subs = '{$user_subs}' WHERE username = '{$username}' ";
$unsubscribe_user = mysqli_query($connection, $query);
echo "Unsubscribed";
}
Let's start over. Let's start here, in fact...
DROP TABLE IF EXISTS users;
CREATE TABLE users
(user_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,email VARCHAR(20) NOT NULL UNIQUE
);
DROP TABLE IF EXISTS user_subs;
CREATE TABLE user_subs
(user_id INT NOT NULL
, sub_id INT NOT NULL
, active TINYINT NOT NULL DEFAULT 1
, PRIMARY KEY(user_id,sub_id)
);
INSERT INTO users VALUES
(1,'b.smyth634#gmail.com'),
(2,'james#gmail.com'),
(3,'f#gmail.com'),
(4,'sally#gmail.com'),
(5,'thomas#gmail.com');
INSERT INTO user_subs (user_id,sub_id) VALUES
(1,5),
(1,2),
(1,1),
(1,4),
(2,1),
(2,2),
(2,4);
SELECT * FROM users;
+---------+----------------------+
| user_id | email |
+---------+----------------------+
| 1 | b.smyth634#gmail.com |
| 2 | james#gmail.com |
| 3 | f#gmail.com |
| 4 | sally#gmail.com |
| 5 | thomas#gmail.com |
+---------+----------------------+
SELECT * FROM user_subs;
+---------+--------+--------+
| user_id | sub_id | active |
+---------+--------+--------+
| 1 | 5 | 1 |
| 1 | 2 | 1 |
| 1 | 1 | 1 |
| 1 | 4 | 1 |
| 2 | 1 | 1 |
| 2 | 2 | 1 |
| 2 | 4 | 1 |
+---------+--------+--------+
SELECT u.*
, GROUP_CONCAT(us.sub_id) subs
FROM users u
JOIN user_subs us
ON us.user_id = u.user_id
GROUP
BY u.user_id;
+---------+----------------------+---------+
| user_id | email | subs |
+---------+----------------------+---------+
| 1 | b.smyth634#gmail.com | 1,2,4,5 |
| 2 | james#gmail.com | 1,2,4 |
+---------+----------------------+---------+
From here we have a choice. We can either DELETE subs we no longer wish to consider, or simply UPDATE them as 'inactive'.
Either way, we just need a DELETE or an UPDATE. So no SELECT needed. In fact a SELECT would, as I mentioned, be counterproductive - because a user may modify the data set in between the execution of the SELECT and the execution of the UPDATE/DELETE. This is known as a 'race condition'.

MySQL query with conditions check

I have a table where it contains user details. Now I need to execute a MySQL query which satisfies the below conditions:
There are two tables
1) user table - which contains userid,name,firstname
2) category table - which containts categoryid, category type, assinged userid
Now I want to execute the query which satisfies the below condition
A User can only sees a category with a type of simple,complex and which are assigned only to his userid and that category shouldn't get assigned to any another userid.
Anyone please help me in this.
drop table if exists category;
create table category (id int, categorytype varchar(10), assignedUserId int);
truncate table category;
insert into category values
(1,'simple',1),
(2,'complex',1),
(3,'simple',2),
(4,'complex',3),
(5,'odd',1);
MariaDB [sandbox]> select * from users where id < 6;
+----+----------+----------+--------+---------------------+
| id | userName | photo | status | ts |
+----+----------+----------+--------+---------------------+
| 1 | John | john.png | 1 | 2016-12-08 13:14:24 |
| 2 | Jane | jane.png | 1 | 2016-12-08 13:14:24 |
| 3 | Ali | | 1 | 2016-12-08 13:14:24 |
+----+----------+----------+--------+---------------------+
3 rows in set (0.00 sec)
MariaDB [sandbox]>
MariaDB [sandbox]> select u.*, c.*
-> from users u
-> join category c on c.assigneduserid = u.id
-> where u.id = 1
-> and c.categorytype not in (select c.categorytype from category c where c.assigneduserid <> 1);
+----+----------+----------+--------+---------------------+------+--------------+----------------+
| id | userName | photo | status | ts | id | categorytype | assignedUserId |
+----+----------+----------+--------+---------------------+------+--------------+----------------+
| 1 | John | john.png | 1 | 2016-12-08 13:14:24 | 5 | odd | 1 |
+----+----------+----------+--------+---------------------+------+--------------+----------------+
1 row in set (0.00 sec)
Try this:
SELECT *
FROM category c
where userid = 123
and not exists (
select 1
from category c2
where c.userid <> c2.userid
and c.categorytype = c2.categorytype
);
Note that this query doesn't require the id to be mentioned at two places unlike the other answer, and hence is a more general one.
SELECT * FROM categories
WHERE category_type = 'simple' OR
category_type = 'complex' AND // (edited after comment of Philipp)
assinged_userid = (Your User ID Here)

How can I check two conditions before inserting?

I have three tables:
// Posts
+----+----------+---------------+-----------+
| id | title | content | id_author |
+----+----------+---------------+-----------+
| 1 | title1 | content1 | 1234 |
| 2 | title2 | content2 | 5678 |
+----+----------+---------------+-----------+
// Users
+----+--------+--------+
| id | name | active |
+----+--------+--------+
| 1 | jack | 1 |
| 2 | peter | 0 |
| 3 | John | 1 |
+----+--------+--------+
// Votes
+----+---------+---------+
| id | id_post | id_user |
+----+---------+---------+
| 1 | 32 | 1234 |
| 2 | 634 | 5678 |
| 3 | 352 | 1234 |
+----+---------+---------+
Now I need to check two conditions before inserting a new vote into Votes table:
The id of author and what I have passed are the same? Posts.id_user = :author (I know I can do that by a FK, but I don't want)
The account of current user is active? Users.active = 1
Also here is my query:
INSERT INTO Votes (id_post,id_user)
SELECT ?,?
FROM Posts p
WHERE p.id_user = :author limit 1;
How can I add second condition Users.active = 1 to my query?
EDIT: Actually I'm trying to don't let people be able to vote who are inactive (active = 0). For example if SO bans men, then I cannot vote to post anymore, because I (current user) am banned. So I'm pretty sure $_SESSION['id'] should be used in the query.
INSERT INTO Votes (id_post,id_user)
SELECT p.id,u.id
FROM Posts p, Users u
WHERE p.id_user = :author
AND u.id = :user
AND u.active = 1 limit 1;
then you set parameter user equal to the current user id.
EDIT: I suppose id_user in table Votes must be the voter's id, not the author of the post (correct?), so I fixed the query eliminating the JOIN.
Use and with where
INSERT INTO Votes (id_post,id_user)
SELECT ?,?
FROM Posts p, Users u
WHERE p.id_user = :author and u.active = 1 limit 1;
INSERT INTO Votes (id_post,id_user)
SELECT p.id, u.id
FROM Posts p
INNER JOIN Users u ON 1 = 1
WHERE p.id_user = :author
AND u.id = :current_user_id
AND u.active = 1
LIMIT 1;

Contitionally structured and ordered MySQL query

I have a table in a MySQL Database.
It is structured as such:
CREATE TABLE `wall` (
`wall_id` int(10) NOT NULL auto_increment,
`user_id` int(10) NOT NULL,
`wall_content` varchar(1024) NOT NULL,
`time_posted` varchar(64) NOT NULL,
`is_reply` int(10) NOT NULL,
PRIMARY KEY (`wall_id`)
) ENGINE=MyISAM
The column 'is_reply' will be the id of 'wall_id' to which it is a reply of. How would I structure a query to get all the rows based on an inner join of another table to cross reference the user_id, and to group the wall posts with the comments below it whilst ordering the wall posts by 'time_posted'
My current query does that without grouping the comments. It is:
SELECT wall.*, user_wall.*, users.username, users.avatar_id
FROM `wall`
INNER JOIN user_wall ON user_wall.wall_id = wall.wall_id
INNER JOIN users ON users.user_id = wall.user_id
WHERE user_wall.user_id=15
I hope you can understand this.
Edit:
The table 'user_wall' is a table that stores what values are on the users wall, and the 'wall' table stores what is actually posted. The user_id in the 'wall' table is a reference to who posted that post.
The current query as stated above is fully functional and returns data as such:
wall_id | user_id | wall_content | time_posted | is_reply | user_id | wall_id | username | avatar_id
1 | 1 | *content* | *time* | 0 | 2 | 1 | User1 | 1
2 | 1 | *content2* | *time2* | 0 | 2 | 2 | User1 | 1
3 | 1 | *content3* | *time3* | 1 | 1 | 3 | User1 | 1
Whereas my question is, how do you structure the query so the result is like so:
wall_id | user_id | wall_content | time_posted | is_reply | user_id | wall_id | username | avatar_id
1 | 1 | *content* | *time* | 0 | 2 | 1 | User1 | 1
3 | 1 | *content3* | *time3* | 1 | 1 | 3 | User1 | 1
2 | 1 | *content2* | *time2* | 0 | 2 | 2 | User1 | 1
Where the row with 'wall_id' 3 which has and 'is_reply' of 1 to be beneath the row with 'wall_id'. Similarly a row with an 'is_reply' of 2 will be under the row with the row with a 'wall_id' of 2.
Now that you've edited it I understand what you mean. This should do it:
ORDER BY IF(wall.is_reply, wall.is_reply, wall.wall_id), wall.wall_id
Format: IF(EXPRESSION, IF_TRUE, IF_FALSE)
SQL can't return multiple rows from one table (e.g. the wall_comments) and only one from the ones it is joined with. In other words, that can't be done. There is an alternative that will get the same results but use two SQL queries and some PHP code.
Query #1:
SELECT wall_comments.*
FROM `wall_comments`
INNER JOIN user_wall ON wall_comments.wall_id = user_wall.wall_id
WHERE user_wall.user_id=15
Query #2:
SELECT wall.*, user_wall.*, users.username, users.avatar_id
FROM `wall`
INNER JOIN user_wall ON user_wall.wall_id = wall.wall_id
INNER JOIN users ON users.user_id = wall.user_id
WHERE user_wall.user_id=15
PHP:
<?php
$result1 = mysql_query($query1);
$result2 = mysql_query($query2);
$comments = array();
while($row = mysql_fetch_assoc($result1))
{
$comments[$row['wall_id']][] = $row;
}
$walls = array();
while($row = mysql_fetch_assoc($result2))
{
$walls[] = array_merge(
$row,
array(
'comments' => isset($comments[$row['wall_id']]) ? $comments[$row['wall_id']] : array(),
),
);
}
?>

Categories