MySQL+PHP array_count_values - php

I need to find the most common value (not 0) from arrays.
My code:
include ("db.php");
$query = "SELECT poll1 FROM names";
$res = mysql_query($query) or die(mysql_error());
while ($row = mysql_fetch_array($res)) {
echo $row['poll1'];
}
And echo results (minimum value 0 (default) and maximum 3):
1
1
0
0
0
2
3
The most common value is "1". I cant use array_count_values, because there are 7 arrays of numbers.

This is a problem you should solve with SQL.
Firstly, you want to get the number of people selecting each option:
SELECT poll1, COUNT(*) AS count FROM names GROUP BY poll1;
+-------+-------+
| poll1 | count |
+-------+-------+
| 0 | 3 |
| 1 | 2 |
| 2 | 1 |
| 3 | 1 |
+-------+-------+
4 rows in set (0.00 sec)
Ok, but you're not interested in zeros, and you only care about the row with the largest value of count so you should sort by descending count, and limit it to 1 result:
SELECT poll1, count(*) AS count FROM names
WHERE poll1 != 0
GROUP BY poll1
ORDER BY count DESC
LIMIT 1;
+-------+-------+
| poll1 | count |
+-------+-------+
| 1 | 2 |
+-------+-------+
1 row in set (0.00 sec)

Related

Check value of last 4 rows

I want to check the value of the last 4 rows from DB. If these 4 rows have a specific value, Do something.
So the table looks like this:
______________
| id | value |
|____|_______|
| 1 | a |
|____|_______|
| 2 | a |
|____|_______|
| 3 | a |
|____|_______|
| 4 | a |
|____|_______|
| 5 | a |
|____|_______|
| 6 | a |
|____|_______|
Here is a fiddle to test with: http://sqlfiddle.com/#!9/1064b3/1
I can run the following query SELECT * FROM testing ORDER BY id DESC LIMIT 4, Then check with PHP:
//Count number of `a` from last 4 rows
$count = 0;
foreach($rows as $row){
if($row['value'] == 'a'){
$count++;
}
}
//If last 4 rows value = 'a'
if($count == 4){
//Do something
}
Is there is a better way with SQL to get the rows only if the 4 rows value = a or return true or false maybe?
Try this:
SELECT COUNT(a.value)
FROM(
SELECT value
FROM testing
ORDER BY id DESC LIMIT 4
) AS a
WHERE a.value = 'a'
If 3 is returned, it's TRUE (You have one not equal to A), FALSE otherwise.
A multitude of ways, you could just use simple aggregation to count the rows:
select case when
count(case when value='a' then 1 end)=Count(*)
then 'true' else 'false'
end Last4AreA
from (
select value
from t
order by id desc
limit 4
)x

mySQL update sort - order from table with unlimited childs after delete one or more

I have a table like this:
id | parent_id | order
1 | 0 | 1
2 | 1 | 1
3 | 1 | 2
4 | 1 | 3
5 | 0 | 2
6 | 0 | 3
7 | 5 | 1
8 | 5 | 2
it takes unlimited categories and childs in the same table by the parent_id.
I have a form with checkboxes to delete one or more and I want to re-ordering after delete one or more rows group by parent_id.
I have write this code:
mysql_query("SET #rownumber = 0;");
$sql_previous_order = "UPDATE `cms` SET `order` = (#rownumber:=#rownumber+1) ORDER by parent_id, `order` ASC";
but it not turn rownumber to zero (0) after change parent_id.
You can introduce an additional variable - p_id. Compare it with parent_id and reset rownumber to 0 when parent_id is changed. Like this
SET #rownumber = 0;
SET #p_id = 0;
select id,
CASE #p_id
WHEN parent_id THEN #rownumber:=#rownumber+1
ELSE #rownumber:=0 END as new_order,
#p_id:=parent_id as p_id
from cms
ORDER by parent_id ASC
;

circular/round loop based on ID (start with specific ID add the rest of the ID, break when specific ID reached)

Consider I have array of IDs:
1
2
3
4
5
6
7
8
Let's say I can fetch an array starting with an ID of specific number, let's say 5.
mysql_query("SELECT * FROM farmlist WHERE id > 4 ORDER BY id")
it should give me array of form:
5
6
7
8
Question: Is there a way after reaching the last ID, it would add to array the IDs from the smallest until the ID of where we start, so that we have:
5
6
7
8
1 <~ Add
2 <~ Add
3 <~ Add
4 <~ Add
Try this query:
mysql_query("SELECT * FROM farmlist WHERE id > 4 UNION ALL SELECT * FROM farmlist WHERE id <= 4");
select id from farmlist
order by
(select if( id > 4, id - 4, id + (select max(id) + 1 from farmlist)))
pseudo-code:
res1 = mysql_query("SELECT * FROM farmlist WHERE id > 4 ORDER BY id");
res2 = mysql_query("SELECT * FROM farmlist WHERE id <= 4 ORDER BY id");
array_merge(res1, res2);
and the final res would be in res1
Consider this:
$ids = array(1,2,3,4,5,6,7,8);
$arr = array(5,6,7,8);
sort($ids);
sort($arr);
$min = $arr[0];
foreach($ids as $id){
if($id>=$min) break;
$arr[]=$i;
}
//array will now be (5,6,7,8,1,2,3,4)
That what you wanted?
With mysql this could be done as
mysql> create table test (id int);
Query OK, 0 rows affected (0.10 sec)
mysql> insert into test values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
Query OK, 10 rows affected (0.03 sec)
Records: 10 Duplicates: 0 Warnings: 0
mysql> select * from test order by case when id >=5 then 0 else 1 end , id ;
+------+
| id |
+------+
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| 10 |
| 1 |
| 2 |
| 3 |
| 4 |
+------+
The above query could be even expanded in a range, lets say I want data from 5 till 7 on the top and rest all after that and this could be done as
mysql> select * from test order by case when id >=5 and id<8 then 0 else 1 end , id ;
+------+
| id |
+------+
| 5 |
| 6 |
| 7 |
| 1 |
| 2 |
| 3 |
| 4 |
| 8 |
| 9 |
| 10 |
+------+

MySQL advanced UPDATE query

I want to set an image as a cover for the album and i do it by choosing it from a radio input that is in a do-while loop. I have put in images table a field named is_cover that takes 1 if the image is set as cover ,or 0 if not.
<input type="radio" name="cover" value="<?php echo $row_images['image_id']; ?>" <?php if($row_images['is_cover'] == 1){ echo "checked=\"checked\""; } ?> />
My question is how can i perform an update query that sets all images is_cover field to 0 and only the image selected gets the value 1.
What i'm trying to say is how can i achieve this:
$is_cover = $_POST['cover'];
$query = "
UPDATE images
SET is_cover = 1
WHERE image_id = {$is_cover}
AND SET is_cover = 0
WHERE image_id <> {$is_cover}
";
This should do the trick for you:
UPDATE images SET is_cover = CASE WHEN image_id = {$is_cover} THEN 1 ELSE 0 END;
From my test:
mysql> select * from first;
+------+-------+
| id | title |
+------+-------+
| 1 | aaaa |
| 2 | bbbb |
| 3 | cccc |
| 4 | NULL |
| 6 | ffff |
+------+-------+
5 rows in set (0.01 sec)
mysql> update first set title = case when id > 4 then 'gggg' else title end;
Query OK, 1 row affected (0.01 sec)
Rows matched: 5 Changed: 1 Warnings: 0
mysql> select * from first;
+------+-------+
| id | title |
+------+-------+
| 1 | aaaa |
| 2 | bbbb |
| 3 | cccc |
| 4 | NULL |
| 6 | gggg |
+------+-------+
5 rows in set (0.00 sec)
You can run 2 Queries here one to set them all to 0 and then setting the one you selected to 1
Execute these 2 queries:
$query = "UPDATE images SET is_cover = 0 WHERE image_id <> {$is_cover}";
$query = "UPDATE images SET is_cover = 1 WHERE image_id = {$is_cover}";
The first query sets all is_cover to zero. The second query sets is_cover to 1 for the selected image.

MySQL query question

I have a simple question regrading MySQL. Is it possible to return the rows between row 'x' and row 'y'? It's sort of hard to explain - for the sake of an example: Return rows 6 through 10, excluding rows 1-5 and rows 11+. Thanks! ;D
Use LIMIT. Remember to combine it with ORDER BY for the results to make any sense.
SELECT fields, ...
FROM table
ORDER BY something_sensible
LIMIT 5, 5
(Start from row 6, take 5 rows)
SELECT * FROM table LIMIT 5, 5
http://dev.mysql.com/doc/refman/5.5/en/select.html and look at LIMIT section
Yes, here's an example:
SELECT * FROM myTable LIMIT 5, 5
From the manual (http://dev.mysql.com/doc/refman/5.0/en/select.html):
The LIMIT clause can be used to constrain the number of rows returned by the SELECT statement. LIMIT takes one or two numeric arguments, which must both be nonnegative integer constants (except when using prepared statements).
With two arguments, the first argument specifies the offset of the first row to return, and the second specifies the maximum number of rows to return. The offset of the initial row is 0 (not 1):
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15
mysql> select * from employees order by emp_id;
+--------+-----------------+---------+
| emp_id | name | boss_id |
+--------+-----------------+---------+
| 1 | f00 | NULL |
| 2 | ali later | 1 |
| 3 | megan fox | 1 |
| 4 | jessica alba | 3 |
| 5 | eva longoria | 3 |
| 6 | keira knightley | 5 |
| 7 | liv tyler | 6 |
| 8 | sophie marceau | 6 |
+--------+-----------------+---------+
8 rows in set (0.00 sec)
mysql> select * from employees order by emp_id limit 2,4;
+--------+-----------------+---------+
| emp_id | name | boss_id |
+--------+-----------------+---------+
| 3 | megan fox | 1 |
| 4 | jessica alba | 3 |
| 5 | eva longoria | 3 |
| 6 | keira knightley | 5 |
+--------+-----------------+---------+
4 rows in set (0.00 sec)
Why don't you use an Auto Increment field? Or you can use LIMIT keyword like:
SELECT * FROM tablename WHERE LIMIT 0, 5
This will show records 1,2,3,4,5

Categories