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

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");

Related

Select where not exists pdo

I have a query
SELECT *
FROM `user`
WHERE NOT
EXISTS (
SELECT *
FROM roleInEvent
WHERE user.userId = roleInEvent.userId
AND eventId = 1
)
AND user.disciplineId =5
Whenever I run this in my mysql console it returns 1 row. This is correct.
However in my php script it returns zero rows while it is exact the same query.
My php script looks like this:
$db = DatabaseHelper::get();
$st = $db->prepare('SELECT *
FROM `user`
WHERE NOT
EXISTS (
SELECT *
FROM roleInEvent
WHERE user.userId = roleInEvent.userId
AND eventId = 1
)
AND user.disciplineId =5');
$st->execute();
if ($st->errorCode() !== \PDO::ERR_NONE) {
return null;
}
Somebody knows what is the problem here?
The solution was easy.
I forgot to return the results to my javascript
You can use too the IN with a NOT like:
SELECT * FROM user WHERE id_user NOT IN ( SELECT other_data FROM roleInEvent WHERE user.userId = roleInEvent.userId AND eventId = 1 ) AND user.disciplineId =5
If the query: SELECT other_data FROM roleInEvent WHERE user.userId = roleInEvent.userId AND eventId = 1 bring to you something, this result not have to exist in the user table.
Other example is:
Users Table:
---------------------------
id_user | name_user
1 fernando
2 urban
And in other table we have the block users:
Block Users:
id_user_block | id_user | name_user
1 1 fernando
2 2 john lennon
So,i want bring to me only users that not exists in the block users table:
The query will be:
SELECT * FROM Users WHERE id_user NOT IN ( SELECT id_user FROM blocked_users )
So, the last query we are getting:
id_user | name_user
2 john lennon
Greetings!

Update table based on conditions from another table

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'.

php mysql group by

this is my table
row | car_id | car_model | car_features |
1 1 CAR 1 Features 1
2 2 CAR 2 Features 2
3 2 CAR 2 Features 3
and i want to make it like
row | car_id | car_model | car_features |
1 1 CAR 1 Features 1
2 2 CAR 2 Features 2, Features 3
and this is my php mysql script:
<?php
$con = mysql_connect("localhost", "root", "root");
mysql_select_db("car", $con);
$format = mysql_query("SELECT c.* , p.*, d.*,f.* ,e.* FROM bsi_car_master c,bsi_car_type p, bsi_car_vendor d, bsi_selected_features f, bsi_car_features e WHERE c.car_type_id=p.id AND c.car_vendor_id=d.id AND c.car_id = f.car_id AND f.features_id = e.id");
$row = 1;
while($srow = mysql_fetch_array($format))
{
blah blah blah....
}
?>
Use GROUP_CONCAT with GROUP BY. Try this -
SELECT `row`, `car_id`, `car_model`, GROUP_CONCAT(`car_features`, ',')
FROM your_table GROUP BY `car_id`
SELECT car_id,car_model,GROUP_CONCAT(car_features,',')
FROM yourtable
GROUP BY car_id,car_model;
$format = mysql_query("SELECT c.* , p.*, d.*,f.* ,e.*,group_concat(`c.car_features`,',') as `carfeatures` FROM bsi_car_master c,bsi_car_type p, bsi_car_vendor d, bsi_selected_features f, bsi_car_features e WHERE c.car_type_id=p.id AND c.car_vendor_id=d.id AND c.car_id = f.car_id AND f.features_id = e.id group by c.car_id");
Hopefully, it's fairly obvious that I'm no PHP coder, but here's another way to do it, without GROUP_CONCAT()...
<?php
/*
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,car_id INT NOT NULL
,car_model VARCHAR(12) NOT NULL
,car_features VARCHAR(20) NOT NULL
);
INSERT INTO my_table VALUES
(1 ,1 ,'CAR 1','Features 1'),
(2 ,2 ,'CAR 2','Features 2'),
(3 ,2 ,'CAR 2','Features 3');
*/
require('path/to/mysqli/connection/stateme.nts');
$query = "
SELECT id
, car_id
, car_model
, car_features
FROM my_table
ORDER
BY car_model;
";
$result = mysqli_query($db,$query);
$car_id = 0;
while($row = mysqli_fetch_assoc($result)){
if ($car_id== $row['car_id']){
echo " >".$row['car_features']."<br>\n";
} else {
echo $row['car_model']."<br>\n >".$row['car_features']."<br>\n";
$car_id = $row['car_id'];
}
} // end of while loop
/*
Outputs...
CAR 1
>Features 1
CAR 2
>Features 2
>Features 3
*/
?>

MySql Tally system with php

I'm trying to condense data that I have in my database into rows with their points tallied to see the most popular.
If I had a data table like:
`data`
item1 item2
1
1 2
1 3
1 3
2 3
And wanted the condensed version to be:
`data_sum`
item1 item2 Tally
1 2 2
1 3 3
2 3 1
How would I achieve this? I have somewhat of an idea here:
$popdata = mysql_query("SELECT * FROM data");
while($add = #mysql_fetch_array($popdata)){
$qitem1 = "SELECT * FROM data_sum WHERE item1='".$add['item1']."'";
$ritem1 = mysql_query($qitem1);
if(mysql_num_rows($ritem1) > 0){
$qitem2 = "SELECT * FROM data_sum WHERE item2='".$add['item2']."'";
$ritem2 = mysql_query($qitem2);
if (mysql_num_rows($ritem2) > 0){
$sql = "UPDATE Tally=Tally + 1 WHERE item1='".$add['item1']."' AND item2='".$add['item2']."'";
$update = mysql_query($sql);
}
else{
$sql = "INSERT INTO data_sum (item1, item2) VALUES('$item1', '$item2')";
$insert = mysql_query($sql);
}
else{
$sql = "INSERT INTO data_sum (item1, item2) VALUES('$item1', '$item2')";
$insert = mysql_query($sql);
}
Yes, I know the total tallies are one more than the rows in the first table. I want the rows with a null column to count towards both tallies with a common factor. This file is going to go through thousands of rows so I want utmost efficiency! Thanks!
All you would need to do is create a new table and then combine an INSERT statement with a GROUP BY'd SELECT statement. This would COUNT() the number of times item1 and item2 were the same and store them in the new tally'd table.
Something along the lines of:
INSERT INTO new_tally_table (item1, item2, Tally)
SELECT item1, item2, COUNT(*)
FROM table
GROUP BY item1, item2
Edit:
Actually re-read the last bit of your question. Think what you want is something like this:
SELECT item1, item2, COUNT(*)
FROM (
SELECT i1.item1, i2.item2
FROM table1 as i1
INNER JOIN (
SELECT DISTINCT item1, item2
FROM table1 WHERE item2 IS NOT NULL
) as i2 ON (i1.item1 = i2.item1)
WHERE i1.item2 IS NULL
UNION ALL
SELECT item1, item2
FROM table1
WHERE item2 IS NOT NULL
) as t
GROUP BY item1, item2
There's probably a better way of writing that though.
There may be a simpler solution, but I can't think of it...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,item1 INT NULL
,item2 INT NULL
);
INSERT INTO my_table (item1,item2) VALUES
(1 ,NULL),
(1 ,2),
(1 ,3),
(1 ,3),
(2 ,3);
SELECT x.item1
, x.item2
, COUNT(DISTINCT y.id)
FROM my_table x
JOIN my_table y
ON y.item1 = x.item1
AND (y.item2 = x.item2 OR y.item2 IS NULL)
AND y.id <= x.id
JOIN
( SELECT item1
, item2
, MAX(id) max_id
FROM my_table
GROUP
BY item1
, item2
) z
ON z.item1 = x.item1
AND z.item2 = x.item2
AND z.max_id = x.id
WHERE x.item2 <> 0
GROUP
BY x.id;
+-------+-------+----------------------+
| item1 | item2 | COUNT(DISTINCT y.id) |
+-------+-------+----------------------+
| 1 | 2 | 2 |
| 1 | 3 | 3 |
| 2 | 3 | 1 |
+-------+-------+----------------------+

Checking users options from default

I have table:
user_id | song_id| points
--------|----------------
2 | 1 | 0
2 | 2 | 1
2 | 3 | 2
2 | 4 | 3
2 | 5 | 4
And I need to check if the user have changed the points value.
Therefore it should be something like:
while ($row = mysql_fetch_array($query)) {
$userID = $row['user_id'];
$songID = $row['song_id'];
$points = $row['points'];
if($songID-$points==1){
echo $userID."<br>";
}
But this will print out every occasion of userID where the song-id - points=1.
I need to print out only these user_id's that have all the values =1 and the username must echo'd only once.
EDIT:
SELECT DISTINCT user_id WHERE (song_id - points) = 1
This is half way there. This echo's user_ids' where the song_id - points = 1, but if the user is reordered (i use jQuery sortable) the list, then there can be some rows that is "song_id - points = 1".
My script must echo only these user_id-s, where users every song_id - points = 1, not only one
SELECT DISTINCT user_id FROM table WHERE (song_id - points) = 1
After edit:
SELECT table.user_id
FROM table
LEFT JOIN (
SELECT user_id, COUNT(*) AS C FROM table) AS T2
ON table.user_id = T2.user_id
WHERE (table.song_id - table.points) = 1
GROUP BY table.user_id
HAVING COUNT(*) = T2.C
You can first filter the users which has modified point values:
SELECT DISTINCT user_id FROM table
WHERE (song_id - points) != 1
Then you can use fetch the users which doesn't fit the above condition:
SELECT DISTINCT user_id FROM table
WHERE user_id NOT IN (
SELECT DISTINCT user_id FROM table
WHERE (song_id - points) != 1
)
According to your last edit this last SQL statement might work.
You can check a working example.
Here is what you're looking for:
select user_id from (
select user_id, if(song_id - points = 1, 0, 1) flag from t
) as S
group by user_id
having sum(flag) = 0
And here is a working example.
In case I didn't understand the requirements this shows all users who don't even have one row in which song_id - points != 1, i.e, all users who have all rows that match song_id - points = 1
Or maybe, if you prefer a different approach that might be more efficient:
select distinct t1.user_id from t t1
where not exists (
select * from t t2
where t2.song_id - t2.points != 1 and t1.user_id = t2.user_id
)
Here is the working example.
Not sure I understand the why of the situation, but a simple control-break structure will achieve the desired result ...
$old_id = '';
$good = false;
while($row = mysql_fetch_array($query)){
//check to see if we have a new user ...
if($row['user_id'] != $old_id){
//check to see if all values were == 1
if($good){
echo $old_id . '<br />';
}
//re-initialize variables
$good = true;
$old_id = $row['user_id'];
}
//if value != 1, we won't print the user ...
if($row['song_id'] - $row['points'] != 1){
$good = false;
}
}
//final end-of-loop condition ...
if($good){
echo $old_id . '<br />';
}
OK, here's a query that's a lot more simple than the join above:
SELECT user_id, sum(song_id) as song_total, sum(points) as point_total, count(*) AS cnt FROM table GROUP BY user_id
If the difference between song_id and points is 1 for every song, then the difference between the totals will equal the number of rows for that user ... so using this query:
while($row = mysql_fetch_array($query)){
if($row['cnt'] == ($row['song_total'] - $row['point_total'])){
echo $row['user_id'] . '<br />';
}
}

Categories