Checking users options from default - php

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 />';
}
}

Related

Fetch current and next row and compare in a loop

I would like to compare two values from a table:
This is my table:
ID;VALUE
1;700
2;600
3;800
4;900
This is my query:
$stmt = $db->query("SELECT ID, VALUE FROM TABLE);
Now i like to compare the result of the current row with the next row. In mysql it was easy beacause i have to set the row number. I did not find any solution with PDO.
This is my code yet:
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$id = $row["ID"];
$val_current = $row["VALUE"];
$row_next = $stmt->fetch(PDO::FETCH_ASSOC);
$val_next = $row["VALUE"];
if ($val_current > $val_next){
echo "$id is greate!";
}else{
echo "$id is less!";
}
}
The Result is:
1 is greater
3 is less
He missed to check the ID 2 agains ID 3 becaue i fetch the next element in the while loop. So i fetch it to get the next value and i fetch again in the loop. Can i reposition the cursor at the end of the loop?
If you are running MySQL 8.0, this is straight-forward with window function lead():
select
t.*,
(value - lead(value) over(order by id) > 0) is_greater
from mytable t
This gives you a boolean flag called is_greater, with following possible values:
1: this value is greater than the next one
0: this value is smaller than the next one
null: there is no next value
Demo on DB Fiddle:
ID | VALUE | is_greater
-: | ----: | ---------:
1 | 700 | 1
2 | 600 | 0
3 | 800 | 0
4 | 900 | null
In earlier versions, one option is to use a correlated subquery:
select
t.*,
(value - (
select t1.value
from mytable t1
where t1.id > t.id
order by t1.id limit 1
) > 0) is_greater
from mytable t
You just need to remember the previous row and use it in the next iteration pretending it's the current one, whereas the current row will serve as the next one.
$row = null;
while($row_next = $stmt->fetch(PDO::FETCH_ASSOC)) {
if ($row !== null)) {
$id = $row["ID"];
$val_current = $row["VALUE"];
$val_next = $row_next["VALUE"];
if ($val_current > $val_next){
echo "$id is greater!";
}else{
echo "$id is less!";
}
echo "\n";
}
$row = $row_next;
}

Sum query not working properly properly sql and php

Why this query instead of displaying the sum of points for each user, it display the sum of all together
I have written an SQL query that displays the sum of all point for all users, whereas I would like it to: display the sum of points for each user.
The table that I have written contains the following:
id | Score
1 | 20
2 | 30
2 | 50
1 | 10
Total table :
id | points
1 | 30
1 | 40
What I want is to add the score for user(1) = 30 and user(2) = 80
Id: 1 = 30 = Fail
Id: 2 = 80 = Pass
The query I have written :
$query = "SELECT SUM(sg.score) as sum, SUM(a.total) as suma FROM points as sg, totalpoints as a
WHERE a.id = 1 GROUP BY sg.id";
And related PHP code is as follows:
<?php
foreach($rowsum as $rowsm):
if( ' '. htmlentities($rowsm['sum']) . '' > 50 )
echo 'Pass';
else if( ' '. htmlentities($rowsm['sum']) . '' >= 40 )
echo 'Failed';
echo ' ' . htmlentities($rowsm['sum'], ENT_QUOTES, 'UTF-8') . '<br>';
endforeach;
?>
You need to group by the users ID:
SELECT SUM(score) as sum FROM points GROUP BY id ORDER BY id
You also have an incorrect WHERE clause
WHERE id=id
isn't needed.
I guess you should look forward using the GROUP BY clause :
SELECT
SUM(score) AS sum
FROM
points
GROUP BY
id
ORDER BY
id
You've omitted the GROUP BY clause:
$query = "SELECT SUM(score) as `sum` FROM points GROUP BY id ORDER BY id";
Your WHERE clause wasn't needed.
You need to do group by as below and it will give you the sum of scores for each user
SELECT SUM(score) as sum FROM points
group by id
ORDER BY id
If you need to find it for a specific user just add a where condition as
SELECT SUM(score) as sum FROM points
where id = 1
The above will give the sum of scores for id = 1 and can change for other values as needed.

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

How to get result from 2 table and dont show duplicates

I have 2 tables
USERS
------------
id | user
1 | john
2 | George
3 | Andy
Text
--------------------------------
id | user |date |text
1 | 1 |2012/10/2 | ABC
2 | 3 |2012/11/2 | ABCD
3 | 2 |2012/12/2 | ABCDE
4 | 2 |2012/1/2 | ABCDE
In the Text table the user column gets the id from the Users table.
I have the following query:
$sql= mysql_query ("SELECT
user.id,
users.user,
CASE
WHEN text.date = CURDATE() THEN '1'
ELSE '0'
END AS 'today',
text.date,
text.text
FROM users user, text text
WHERE users.id = text.user;");
if (mysql_num_rows($sql)<=0)
echo "NO ENTRIES FOUND";
while ($row = mysql_fetch_assoc($sql))
{
$user =$row['user'];
$id =$row['id'];
$date2 =$row['date'];
if ($row['today'] == 1) { echo"
<div class='z'><a href='viewuser.php?id=$user'>$user</a></div><br>
"; } else { echo"
<div class='zx'><a href='viewuser.php?id=$user'>$user</a></div><br>
"; };
}
My question is:
How can I display the users whose date is equal with today's date, the first div(zx), and if not with the second div(z), comparing from 2 tables and display once if is it 2 times the user.
<!-- language: lang-sql -->
SELECT
u.id,
u.user,
CASE
WHEN t.date = CURDATE() THEN '1'
ELSE '0'
END AS 'today',
t.date,
t.text
FROM users u, text t
WHERE u.id = t.user;
Now to display the results just say
if ($row['today'] == 0) { class="zx"; } else { class="z"; }
Code is abbreviated, let me know if you need it detailed out.
Here is your updated code with my solution from above:
$sql = mysql_query ("
SELECT
u.id,
u.user,
CASE
WHEN MAX(t.date) = CURDATE() THEN '1'
ELSE '0'
END AS 'today'
FROM users u, text t
WHERE u.id = t.user
GROUP BY u.id, u.user");
if (mysql_num_rows($sql) <= 0)
echo "NO ENTRIES FOUND";
while ($row = mysql_fetch_assoc($sql))
{
$user =$row['user'];
$id =$row['id'];
if ($row['today'] == 1) {
echo "<div class='zx'><a href='viewuser.php?id=$id'>$user</a></div><br>";
} else {
echo "<div class='z'><a href='viewuser.php?id=$id'>$user</a></div><br>";
}
}

PHP/MySQL - Ranking based on last db column

I’ve two tables (MySQL): player and scores. In scores table are stored annual scores in this way:
player_id | 2002 | 2003 | 2004
1 | 5 | 6 | 4
2 | 3 | 2 | 5
Etc.
I write the follow code to make a ranking based on last year scores.
$extract = mysql_query("SELECT * FROM players AS p, scores AS s WHERE p.player_id =s.player_id ORDER BY s.2004 desc");
while ($row = mysql_fetch_assoc($extract)) {
$name = $row['name'];
$score = $row['2004'];
if ($row['2004'] < $row['2003']) {
$value = "-";
}
else if ($row['2004'] > $row['2003']) {
$value = "+";
}
else if ($row['2004'] == $row['2003']) {
$value = "=";
}
echo "<b>".$name."</b> | ".$score." ".$value."<br>\n";
}
But this code has two big problems:
1) In the query I have to specify the last year (ORDER BY s.2004), so if I add another column (eg. 2005) into scores table, I have to manually change the code.
2) Same thing for the “$value” var. If I add 2005, the comparison between 2004 and 2003 becomes wrong (it should be between 2005 and 2004).
I know I have to use loops and array but... how?
You should redesign your scores table to store player_id, score and year in one row. So, each score gets its own row. When you find yourself duplicating columns, you are usually heading in the wrong direction.
Then, your query would look like:
Select Year(CURDATE());
select *
from players p
inner join scores s on p.player_id = s.player_id
where s.`Year` = Year(CURDATE()) --or (select max(Year) from Score)

Categories