How to update one table based on another one? - php

I have these two tables:
// user
+----+-------+------------+
| id | name | total_rep |
+----+-------+------------+
| 1 | Jack | 100 |
| 2 | Peter | 334 |
| 3 | John | 1 |
| 4 | Ali | 5463 |
+----+-------+------------+
// rep
+----+------------+---------+------+
| id | reputation | id_user | done |
+----+------------+---------+------+
| 1 | 5 | 2 | 1 |
| 2 | 2 | 3 | 1 |
| 3 | 15 | 2 | Null |
| 4 | 10 | 2 | Null |
| 5 | 5 | 4 | 1 |
| 6 | 10 | 3 | Null |
+----+------------+---------+------+
I'm trying to sum the number of reputation column from rep table where done is Null for specific user and then add it to total_rep column from user table. So it is expected output:
// specific user
$id = 2;
// user
+----+-------+------------+
| id | name | total_rep |
+----+-------+------------+
| 1 | Jack | 100 |
| 2 | Peter | 359 | -- this is updated
| 3 | John | 1 |
| 4 | Ali | 5463 |
+----+-------+------------+
Note: Then I will update done column and set all Null values for that user to 1. (this is not my question, I can do that myself)
How can I do that?

One way to do it is to use the result of a subquery as a scalar value in an update statement.
UPDATE `user`
SET total_rep = total_rep + (
SELECT SUM(reputation) AS rep_sum FROM `rep` WHERE done IS NULL AND id_user = 2)
WHERE id = 2;

You can't update two tables in one statement, so you will need to execute a transaction. Or maybe in some code do the next thing I'll make it in PHP
$query_result=DB::select('Select sum(reputation) as reputation, id_user from rep where done is null group by id_user');
foreach($query_result as $result){
//update the data
}
You have to take the data and update firstable the reputation table to clean it and then the user table to sum the rep values

Related

Query Select and Show All First Table And Second Table Even is not Exist in Second Table

SAMPLE TABLE
TABLE FIRST_TABLE
| rid | requirements |
| 1 | 2x2 pic |
| 2 | valid id |
| 3 | 137 form |
| 4 | app form |
Second table
| id | applicant_id | rid | remarks |
| 1 | 1 | 1 | pass |
| 2 | 1 | 2 | pass |
| 3 | 2 | 1 | pass |
How to select all records from first table and show even the data is not exist on second table.
Result should be like this.
applicant_id | rid | remarks |
1 | 1 | pass |
1 | 2 | pass |
1 | 3 | null |
1 | 4 | null |
this is my sample code.
select requirements from first_table
left join second_table on first_table.rid = second_table.rid
where second_table.applicant_id = 1
group by first_table.rid
//result :
applicant_id | rid | remarks |
1 | 1 | pass |
1 | 2 | pass |
You just need to move the second_table.applicant_id = 1 to the join.
select requirements, first_table.rid, remarks
from first_table
left join second_table on
first_table.rid = second_table.rid and
second_table.applicant_id = 1
group by first_table.rid
http://sqlfiddle.com/#!9/a0cffdd/17

Find the ranking for Concatenated rows in mysql

I have a table with concatenated values within both rows, I am therefore uniquely retrieve ranking for each row in the tables.
UPDATE
The other tables has been added to question
NamesTable
NID | Name |
1 | Mu |
2 | Ni |
3 | ices |
GroupTable
GID | GName |
1 | GroupA |
2 | GroupB |
3 | GroupC |
MainTable
| NID | Ages | Group |
| 1 | 84 | 1 |
| 2 | 64 | 1 |
| 3 | 78 | 1 |
| 1 | 63 | 2 |
| 2 | 25 | 2 |
| 3 | 87 | 2 |
| 1 | 43 | 3 |
| 2 | 62 | 3 |
| 3 | 37 | 3 |
Now the first Name is equated to the first age in the table, I am able to equate them using php and foreach statements, Now the problem is with the ranking of the ages per each group. I am ranking the names uniquely on each row or group.
Results which is expected
| Names | Ages | Group | Ranking |
| Mu,Ni,ices | 84,64,78 | 1 | 1,3,2 |
| Mu,Ni,ices | 63,25,87 | 2 | 2,3,1 |
| Mu,Ni,ices | 43,62,37 | 3 | 2,1,3 |
In my quest to solving this, I am using GROUP_CONCAT, and I have been able to come to this level in the below query
SELECT
GROUP_CONCAT(Names) NAMES,
GROUP_CONCAT(Ages) AGES,
GROUP_CONCAT(Group) GROUPS,
GROUP_CONCAT( FIND_IN_SET(Ages, (
SELECT
GROUP_CONCAT( Age ORDER BY Age DESC)
FROM (
SELECT
GROUP_CONCAT(Ages ORDER BY Ages DESC ) Age
FROM
`MainTable` s
GROUP by `Group`
) s
)
)) rank
FROM
`MainTable` c
GROUP by `Group`
This actually gives me the below results.
| Names | Ages | Group | Ranking |
| 1,2,3 | 84,64,78 | 1 | 7,9,8 |
| 1,2,3 | 63,25,87 | 2 | 5,6,4 |
| 1,2,3 | 43,62,37 | 3 | 2,1,3 |
The only problem is that the ranking Values increase from 1 to 9 instead of ranking each row uniquely. Its there any idea that can help me cross over and fix this? I would be grateful for your help. Thanks

SQL PHP - match records from one table to another based on several columns

I have 2 tables:
tbl1:
+-------+-------+
| p_id | f_id |
+-------+-------+
| 1 | 2 |
| 1 | 4 |
| 2 | 1 |
| 3 | 4 |
| 4 | 1 |
| 4 | 3 |
+-------+-------+
tbl2:
+-------+-------+-------+
| u_id | fname | lname |
+-------+-------+-------+
| 1 | adam | smith |
| 2 | jon | jones |
| 3 | sean | dent |
| 4 | jack | scott |
+-------+-------+-------+
my logged in id (php) is:
$user->id // this returns '3'
I need to return each u_id in tbl2 for each p_id in tbl1 that does NOT have my $user->id (3 in this example) in it's corresponding f_id. For example, 4 should not be returned because it has a 3 in one of it's f_id's. I hope this makes sense!!! Many thanks..
I think this query should work for you.
SELECT u_id FROM tbl2
WHERE u_id NOT IN
(SELECT p_id FROM tbl1
where f_id = $user);
You will need to build the query in PHP so that it boils down to the above query in SQL.

Sorting a group of users among themselves in users table

I have users table and I store all users (administrators, authors and normal users) in this table. I want to order authors (who writer column posts in a newspaper) among themselves. So which way should I follow? I have no idea what to do about it. Although I tried some methods. I added an "order" column to users table and I don't know what do to next. Please give me some advice. My table structure:
+----+-----------------+------------------+-------+-----------+-------+
| id | username | password | order | is_author | level |
+----+-----------------+------------------+-------+-----------+-------+
| 1 | admin2 | pass | 0 | 0 | 3 |
| 2 | admin1 | pass | 0 | 0 | 3 |
| 3 | writer&admin | pass | 0 | 1 | 3 |
| 4 | normaluser | pass | 0 | 0 | 0 |
| 5 | writer | pass | 0 | 1 | 1 |
+----+-----------------+------------------+-------+-----------+-------+
Additional info:
Level 3 - Super Administrator
Level 2 - Editor (Only can add news and manage users)
Level 1 - Author
Level 0 - Normal users
Why do I need is_author colunm?
Because every editor or super administrator isn't writer. For those who both author and administrator I added a additional column, is_author.
Give me some advice.
For your approach, create 2 tables -
1) users
2) user_role
users table:
+----+-----------------+------------------+--------------+----------+
| id | username | password | role_id (FK) | priority |
+----+-----------------+------------------+--------------+----------+
| 1 | admin2 | pass | 1 | NULL |
| 2 | admin1 | pass | 1 | NULL |
| 3 | writer&admin | pass | 2 | 1 |
| 4 | normaluser | pass | 4 | NULL |
| 5 | writer | pass | 3 | 3 |
+----+-----------------+------------------+--------------+----------+
user_role table:
+----+---------------------------+--------+
| id | role | level |
+----+---------------------------+--------+
| 1 | admin | 1 |
| 2 | writer and admin | 2 |
| 3 | writer | 3 |
| 4 | user | 4 |
+----+---------------------------+--------+

PHP and MYSQL select with 5 tables and multiple rows as a single array

Would like to get the following as a result from the table structure below (MYSQL + PHP)
array[0][name]1,[desc]red,[title]hero,[desc]strong,[desc2]smells,[img][0]red1,[img][1]red2,[img][2]red3,ext[0].jpg,[ext][1].gif,[ext][2].png,[count][0]253,[count][1]211,[count][2]21,[count][3]121,[dist][0]5,[dist][1]5,[dist][2]12,[dist][3]2,[score][0]2,[score][1]3,[score][2]1,[score][3]5,[score][4]4,[val][0]5,[val][1]1,[val][2]4,[val][3]3,[val][4]4
The problem I have with a simple SELECT, JOIN and GROUP_CONCAT is that the values duplicate after selecting all the images.
I've tried various other ways for example selecting the data by row combined with a foreach loop in PHP, but I end up with lots of duplicates, and it looks very messy.
I also though about splitting it into multiple selects instead of using one, but I really would like to know if it can be done with one select.
Could someone help me with an MYSQL select? Thanks
game
+-----+----------+
| pid | name |
+-----+----------+
| 1 | red |
| 2 | green |
| 3 | blue |
+-----+----------+
detail
+-----+------+--------+-------+--------+
| id | pid | title | desc | desc 2 |
+-----+------+--------+-------+--------+
| 1 | 1 | hero |strong | smells |
| 2 | 2 | prince |nice | tall |
| 3 | 3 | dragon |big | green |
+-----+------+--------+-------+--------+
image
+-----+-----+-----+----+
| id | pid | img |ext |
+-----+-----+-----+----+
| 1 | 1 | red1|.jpg|
| 2 | 1 | red2|.gif|
| 3 | 1 | red3|.png|
+-----+-----+-----+----+
devmap
+-----+-----+-------+------+
| id | pid | count | dist |
+-----+-----+-------+------+
| 1 | 1 | 253 | 5 |
| 2 | 1 | 211 | 5 |
| 3 | 1 | 21 | 12 |
| 4 | 1 | 121 | 2 |
+-----+-----+-------+------+
stats
+-----+-----+-------+------+
| id | pid | scrore| val |
+-----+-----+-------+------+
| 1 | 1 | 2 | 5 |
| 2 | 1 | 3 | 1 |
| 3 | 1 | 1 | 4 |
| 4 | 1 | 5 | 3 |
| 5 | 1 | 4 | 3 |
+-----+-----+-------+------+
When you do a JOIN that involves more than a 1:1 mapping between tables you're going to have duplicate data, and there's no way to get around that in the query.
You can break it out into multiple selects, or you can loop through the result set and pare out whatever duplicate information you don't want.

Categories