Update table based on conditions from another table - php

I have 2 database tables
1- users
id points
1 100
2 3
3 1
2- user_pages
user_id lp_flag
1 0
2 0
3 0
I am trying to update lp_flag = 1 if any id points < 5 in users table.
Here is my code i want to run it using cron job only.
$Point_row = mysql_query("SELECT * FROM users WHERE points < 5 ");
foreach($Point_row as $val){if($val['points']<5) {
mysql_query("UPDATE user_pages SET lp_flag = '1' WHERE user_id = '$id'")
}else{
mysql_query("UPDATE user_pages SET lp_flag = '0' WHERE user_id = '$id'") }
}
}
expected results
user_pages
user_id lp_flag
1 0
2 1
3 1
becasue id's 2 & 3 points are <5 in users table.

You should do this in one query:
update user_pages up join
users u
on up.user_id = u.id
set up.lp_flag2 = (case when u.points < 5 then 2 else 0 end);
There is no need for a loop on the application side.

You can use this:
UPDATE user_pages SET lp_flag = 1
WHERE user_id IN (SELECT id FROM users WHERE points < 5)
If default value of lp_flag is '0' than no need to use ELSE condition for UPDATE '0'.

Related

MySQL - Update Column if all rows are equal

I have N Rows with same SlNo but different RowNo as shown below
for eg:
SlNo RowNo Status
1 1 Opened
1 2 Closed
1 3 Opened
1 4 Closed
1 5 Opened
If all the Status Column Rows are Closed , I want to return 1.
else o.
Thanks in advance.
You can do it following:
SELECT STATUS FROM `table_1` where SLNO = 1 group by status
If you get only one record with value "Closed" then execute the next query
UPDATE `table_2` SET Ref_Status = 'Closed' WHERE SLNO = 1;
Update my_table set Status='Closed' where SlNo = 1
Find the count of all rows and check it with the count of Closed values.
Query
select t.`SlNo`,
case when t.`RowNo_Count` = t.`closed_count` then 1 else 0 end as `new_col`
from(
select `SlNo`,
count(`RowNo`) as `RowNo_Count`,
sum(case `Status` when 'Closed' then 1 else 0 end) as `closed_count`
from `your_table_name`
group by `SlNo`
)t;

count id, insert, then update by number range in another columns in same table mysql

I am trying to update levels in db like this:
"count (id) from users table where referral_id = id As aggref set agg_referral = aggref AND level = 1 if aggref in between 1 to 3"
So far i know but no success :(
Here is my db structure
users table:
id (AI) name Referral id agg_referral Level
=========== ========== ================== ============== ======
1 user A 0 0 0
2 user B 3 0 0
3 user C 1 0 0
4 user D 3 0 0
Here is my code i am running it using cron job:
<?php
include( $_SERVER['DOCUMENT_ROOT'] . '/config.php' );
mysql_connect(DB_HOST,DB_USER,DB_PASS);
mysql_select_db(DB_NAME);
$query="UPDATE users SET agg_referral = (SELECT COUNT(id) from users WHERE users.referral_id = users.id)";
mysql_query($query);
?>
I am expecting results like this
id (AI) name Referral id agg_referral Level
=========== ========== ================== ============== ======
1 user A 0 0 0
2 user B 3 0 0
3 user C 1 2 1
4 user D 3 0 0
You can use an update join:
update users u1
join (
select referral_id,
count(*) cnt
from users
group by referral_id
) u2 on u1.id = u2.referral_id
set u1.agg_referral = u2.cnt,
u1.level = case
when cnt < 1
then 0
else ceil((- 5 + sqrt(25 + 8 * cnt)) / 2)
end;
Demo
It finds times an id is referred and then join it with the table to update the counts and level.
The case statement produces 0 for cnt = 0 or less, 1 for cnt between 1 and 3, 2 for cnt between 4 and 7 and . . so on.
To learn more on how the formula works, see https://math.stackexchange.com/questions/2171745/find-group-number-for-a-given-number-from-groups-of-increasing-size
EDIT:
If your initial group size is value other than 3, use this to get the required equation:
ceil((1 - 2 * g + sqrt(4 * g * g + 1 - 4 * g + 8 * cnt)) / 2)
where g is the intial size of the group.
For g = 3, it solves to:
ceil( -5 + sqrt(25 + 8 * cnt) / 2 )
for g = 10, it solves to:
ceil( -19 + sqrt(361 + 8 * cnt) / 2 )
On how this function is made, see the link provided above.
In MySQL, you can do this by counting the number of referrals for each id using a subquery. Then use that information in the update:
UPDATE users u JOIN
(SELECT referral_id, COUNT(*) as cnt
FROM users u
GROUP BY referral_id
) ur
ON u.id = ur.referral_id
SET u.agg_referral = ur.cnt,
u.level = (CASE WHEN ur.cnt BETWEEN 1 and 3 THEN 2 ELSE level END);

Fetch row with different data on same column

We have the table structure like
Fieldid userid data
41 2 1
12 2 0
41 3 1
12 3 1
We want the user which have (data=1 and filedid = 41) and (data = 0 and filedid=12)
We tried the query
select userid from table
where (data=1 and filedid = 41)
AND (data = 0 and filedid=12)
but it returns empty results.
Can anyone help how we will get the record using MySQL?
You can use grouping with a conditional aggregate in the HAVING clause:
SELECT userid
FROM mytable
GROUP BY userid
HAVING COUNT(CASE WHEN data = 1 AND FieldId = 1 THEN 1 END) >= 1 AND
COUNT(CASE WHEN data = 0 AND FieldId = 12 THEN 1 END) >= 1
you need to use union all like:
select * from table1 where Fieldid = 41 and data = 1 union all
select * from table1 where Fieldid = 12 and data = 0
attached image shows the output
Similar to #Giorgos, with multicolumn compare for conciseness:
select userid
from t
group by userid
having sum((data,fieldId) = (1, 41)) > 0
and sum((data,fieldId) = (0, 12)) > 0
When searching for results with one or another set of data you have to use OR keyword, not AND.
SELECT userid FROM table
WHERE (data = 1 AND filedid = 41)
OR (data = 0 AND filedid = 12)

PHP/Mysql: 2 selects from same table in one query

This is how my table looks like:
id | name | value
-----------------
1 | user1| 1
2 | user2| 1
3 | user3| 3
4 | user4| 8
5 | user5| 6
6 | user7| 4
7 | user8| 9
8 | user9| 2
What I want to do is to select all the other users, in one query, who's value is user1's value lower than it's value plus 3, higher than it's value minus 3 or equal to it's value.
Something like this:
$result = mysqli_query($con,"SELECT * FROM users WHERE value<'4' OR value>'-2'") or die("Error: ".mysqli_error($con));
while($row = mysqli_fetch_array($result))
{
echo $row['name'].'<br/>';
}
The problem is that users1's value can vary every time the query is run.
Sorry for lame names, but this should work:
NOTE: I named table with your data as "st".
SELECT b.user, a.value as "user1val", b.value as "otheruservalue" FROM st as a
join st as b
on a.user = "user1" and a.user != b.user
where
(b.value > (a.value - 3)) and (b.value < (a.value + 3))
We get unique pairs of user1's value and other user's value by joining same table. After that we just do some simple comparison to filter rows with suitable values.
$user1 = mysql_fetch_assoc(mysql_query("SELECT `value` FROM `users` WHERE id='1'"));
$result = mysql_query("SELECT * FROM `users` WHERE value<'".$user1['value']."+3' OR value>'".$user1['value']."-3'");
Or nested queries :
$result = mysqli_query($con, "select * from `users` where `value` < (select `value` from `users` where `name`='user1')+3 OR `value` > (select `value` from `users` where `name`='user1')-3");

Order by ID if two users have same number of credits

:-)
I have this script, which find a users position taken from the number of credits.
It all works, but i have a little problem. If two users have the same credits, both of them will be on the same position.
Can I do, so if there are more users with same credits, then the system need to order by the users ID and out from that give them a position?
This is my code so far:
$sql = "SELECT COUNT(*) + 1 AS `number`
FROM `users`
WHERE `penge` >
(SELECT `penge` FROM `users`
WHERE `facebook_id` = ".$facebook_uid.")";
$query_rang = $this->db->query($sql);
So if i have this:
ID -------- Credits
1 -------- 100
2 -------- 100
3 -------- 120
Then the rank list should be like this:
Number 1 is user with ID 3
Number 2 is user with ID 1
Number 3 is user with ID 2
ORDER BY credits DESC, id ASC. This will sort by credits and break ties with the id.
UPDATE
I understand now that you want the ranking information for the user, not just to sort the users by credits and ids. This will give you the complete list of users and their rankings:
SELECT #rank:=#rank+1 AS rank, users.id, users.facebook_id FROM users, (SELECT #rank:=0) dummy ORDER BY penge DESC, id ASC
Getting the row number is the tricky bit solved by this blog post:
http://jimmod.com/blog/2008/09/displaying-row-number-rownum-in-mysql/
$sql = "SELECT COUNT(*) + 1 AS `number` FROM `users` WHERE `penge` > (SELECT `penge` FROM `users` WHERE `facebook_id` = ".$facebook_uid.") ORDER BY COUNT(*) + 1 desc, users.ID";
$query_rang = $this->db->query($sql);
Later EDIT:
I don't understand why you still have the same results....
I made a quick test. I have created a table:
Test: ID (Integer) and No (Integer)
I have inserted some values:
id no
1 1
1 1
1 1
2 1
3 1
4 1
4 1
5 1
Now, if I run:
SELECT
id, COUNT(*) + 1 AS `number`
FROM
test
GROUP BY
id
I get:
id number
1 4
2 2
3 2
4 3
5 2
But if I add ORDER BY:
SELECT
id, COUNT(*) + 1 AS `number`
FROM
test
GROUP BY
id
ORDER BY
count(*) desc, id
then I get:
id number
1 4
4 3
2 2
3 2
5 2

Categories