I'm trying to show only every 2nd row after selecting something from my DB.
My select looks like this:
SELECT * FROM table where partnerID = '1'
Now from the results of that select query I want to get only every 2nd row.
Is that possible ?
$count = 0;
while($row = mysql_fetch_array($results)) {
$count++;
if($count % 2 == 1) continue;
// What you want to do with the rows you don't want to skip here...
}
On a side note, you can use this same strategy to only show every 3rd row, or every 4th row, simply by changing what number you put next to the modulus operator
if($count % 3 != 0) continue; // Show only every third row
if($count % 4 != 0) continue; // Show only every fourth row
SELECT * FROM (
SELECT #n := #n + 1 AS position,
t.*
FROM (SELECT #n:=0) counter,
table t
WHERE partnerID = 1)
AS query
WHERE MOD(position,2) = 0
You can do this in the following way:
SELECT * FROM
(
SELECT
#I := #I + 1 AS rowNumber,
tablename.*
FROM
tablename,
(SELECT #I := 0) VT1
WHERE partnerID = 2
ORDER BY ID
) NumberedRows
WHERE MOD(rowNumber, 2)=0
;
Not sure if this is the right answer, but it looks like you would need to use something like MOD function (http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_mod)
SELECT * FROM `table` WHERE id & 1;
Would return odd rows
Related
Suppose I have a table TABLE:
NAME ID ...
m -1 ...
f -1 ...
g -1 ...
b -1 ...
z -1 ...
And I want to turn it into:
NAME ID ...
f 1 ...
g 2 ...
m 3 ...
b -1 ...
z -1 ...
You probably get the idea:
select the first 3 rows from the original table (preserving order)
order selected rows by the NAME column.
update selected rows' IDs with their position in the new table (keeping the remaining unselected rows in their original positions).
So (m, f, g) got sorted to (f, g, m) and (b, z) remained (b, z).
Here's how I am trying to do it in PHP:
$count = 0;
$query = "UPDATE TABLE SET ID = $count:= $count + 1 ORDER by NAME DESC LIMIT 3";
mysqli_query($con, $query);
But I don't think I can just go ahead and increment a counter and store its value like that. Any advice?
You can try this :
$limit = 3;
for($count = 0 ; $count < $limit;$count++ ){
$query = "UPDATE TABLE SET ID = $count + 1 WHERE ID = '-1' ORDER by NAME DESC";
mysqli_query($con, $query);
}
$query = "UPDATE TABLE SET ID = '-1' WHERE ID > $limit ORDER by NAME DESC";
mysqli_query($con, $query);
In the above logic :
In the final loop, all the IDs are set to $limit
However the update command outisde the loop will set back IDs to -1 again
First, you can quickly query for the first 3 rows in the table and get the name property only and assign the value in an array.
$sql = "select name from table order by name limit 3"
$query = $mysqli->query($sql);
Now let's construct a helper array:
while ($row = $mysqli->fetch_assoc()) {
$a[] = $row['name'];
}
Now just structure the queries:
foreach($a as $id => $name) {
$query = "update table set id={$id+1} where name='$name' limit 1";
// execute the query
}
Note that I assume that the name is unique so I added the limit 1 directive to tell it stop looking for rows to update once it has found a row.
Also, don't forget that array keys are counting starting from 0, hence we are adding 1 to the $id in the loop.
There may be more elegant solutions but this one is rather easy to understand and use.
In MySQL:
SET #row_number = 0;
update TABLE d
join
(
select
NAME,
#row_number:=#row_number+1 as ID,
from
(select NAME from TABLE limit 3) t
order by
NAME asc
) s on s.NAME = d.NAME
set d.ID = s.ID;
SQLFiddle: http://sqlfiddle.com/#!9/dffecf/1
This assumes NAME is your unique key, otherwise likely best to replace with an Identity column in your table and use that for the update.
This approach may require some syntax changes depending on your DB engine. By doing this in SQL, we only make one pass at the DB. Not a huge deal to iterate in multiple passes with PHP if you're only updating three records, but if it was a 1000, etc.
I would like get number of records in a table then divide them by 4, after dividing them by 4 i want to create sql statements with limit ranges based on my result. For example I have a table with 8 records I divide by 4, I will create 2 sql statements with a limit range like limit 0,4 and limit 4,8
Final results will look like
Select * from prop where id=123 LIMIT 0,4
Select * from prop where id=123 LIMIT 4,8
My approach was to have for loop which will count the number of sql statements to be made.
Then in the loop: first circle 0-4 and second will be 4-8
Am struggling on the limit 0-4 and limit 4-8
PHP script
include('connect.php');
$query_1 = "Select COUNT(*) as Total from prop where ref = 'SB2004'";
$results_query_1 = mysql_query($query_1);
while($row_query_1 = mysql_fetch_array($results_query_1))
{
$cnt = $row_query_1['Total'];
}
echo $cnt;
echo "<br>";
$num_grps = 0;
if ($cnt % 4 == 0 )
{
echo $num_grps = $cnt / 4 ;
}
$count_chk= $num_grps * 4;
for ($i=1;$i<=$num_grps;$i++)
{
//for loop for range
for()
{
$range = '0,4';
echo "SELECT prop_ref from prop limit".$range;
}
}
Either you've not understood the problem or haven't explained it very well.
The most immediate problem here is that you have misunderstood the syntax for the LIMIT clause. The first argument specifies the offset to start at and the second defines the number of rows to return, hence LIMIT 4,8 will return 8 rows (assuming there are 12 or more rows in the dataset).
The next issue is that you've not said if the results need to be reproducible - e.g. if you have rows with primary keys 1 and 2, should these always be returned in the same query. In the absence of an explicit ORDER BY clause, the rows will be returned based on the order in which they are found by the query.
The next issue is that you've not explained how you want to deal with the last case when the total number of rows is not an even multiple of 4.
The code you've provided counts the number of rows where ref = 'SB2004' but then creates queries which are not filtered - why?
The code you've provided does not change the limit in the queries - why?
The next issue is that there is never a good reason for running SELECT queries inside a loop like this. You didn't exlpain what you intend doing with the select queries. But based on the subsequent update....
include('connect.php');
$query_1 = "Select COUNT(*) as Total from prop where ref = 'SB2004'";
$cnt = mysql_fetch_assoc(mysql_query($query_1));
$blocks=$cnt['Total']/4 + (0 == $cnt['Total'] % 4 ? 0 : 1);
$qry2="SELECT * FROM prop where ref='SB2004' ORDER BY primary_key";
$res=mysql_fetch_assoc($qry2);
for ($x=0; $x<$blocks; $x++) {
print "<div>\n$block<br />\n";
for ($y=0; $y<4; $y++) {
print implode(",", #mysql_fetch_assoc($res)). "\n";
}
print "</div>\n";
}
It's trivial to refine this further to only issue a single query to the database.
If you really must generate individual SELECTs....
include('connect.php');
$query_1 = "Select COUNT(*) as Total from prop where ref = 'SB2004'";
$cnt = mysql_fetch_assoc(mysql_query($query_1));
$blocks=$cnt['Total']/4 + (0 == $cnt['Total'] % 4 ? 0 : 1);
for ($x=0; $x<$blocks; $x++) {
$y=$x*4;
print "SELECT * FROM prop where ref='SB2004'
ORDER BY primary_key LIMIT $y,4<br />\n"
}
i have a table in mysql and i am fetching the results from this table. but instead of fetching all the rows in this table i only want to fetch every other row. so first get row one then skip the second row, get row 3 and skip row 4 etc.
Is there a way of doing this and if so can someone please show me how.
I've tried this:
function:
function blocked_users_list() {
global $connection;
global $_SESSION;
global $profile_id;
$query = "SELECT
baseview.*
#odd:=1-#odd AS even
FROM
(
SELECT *
FROM ptb_block_user
WHERE
WHERE ptb_block_user.blocked = '1'
AND ptb_block_user.blocked_id = ".$_SESSION['user_id']."
) AS baseview,
(
SELECT #odd:=0
) AS filter
WHERE
even=1
";
$blocked_users_list = mysql_query($query, $connection);
confirm_query($query, $connection);
return $blocked_users_list;
}
php:
<?php
$blocked_users_list = blocked_users_list();
while ($block = mysql_fetch_array($blocked_users_list)) {
?>
but it gives this error:
Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in /Applications/XAMPP/xamppfiles/htdocs/ptb1/blocked_users.php on line 44
do it in the query:
SELECT *
FROM (
SELECT
#row := #row +1 AS rownum, [column name]
FROM (
SELECT #row :=0) r, [table name]
) ranked
WHERE rownum % [n] = 1
You can use modulus in mysql (one query)
select * from `table` where `id` % 2 = 1
Retrieves all odd IDs.
Assuming you have a query like
SELECT
col1 AS colA,
col2 AS colB
FROM
sometable
WHERE
something=17
that fetches all rows as a baseline. You can then filter every second row by using
SELECT
baseview.*
#odd:=1-#odd AS even
FROM
(
SELECT
col1 AS colA,
col2 AS colB
FROM
sometable
WHERE
something=17
) AS baseview,
(
SELECT #odd:=0
) AS filter
WHERE
even=1
Use a variable to record the index, then check with mod 2 ($ind % 2) - this will return either 0 or 1.
<?php
$users_list = users_list();
$ind = 0;
while ($user = mysql_fetch_array($users_list)) {
if(($ind++)%2) echo "something";
}
?>
I have a table with 10 rows. I want to get first and any 3 random rows. Is it possible to do in one query?
Thanks,
aby
I'd do:
SELECT * FROM Foo ORDER BY ID LIMIT 1 --First row
UNION
SELECT * FROM Foo WHERE ID NOT IN (SELECT ID FROM Foo ORDER BY ID LIMIT 1)
ORDER BY RAND() LIMIT 3
(SELECT * FROM table ORDER BY id ASC LIMIT 1) UNION (SELECT * FROM table ORDER BY RAND() LIMIT 3)
Of course, you may want to not select the first row in the random part, but you said ANY 3
I would recommend doing this at the app layer, as you can introduce caching later. Plus it's much faster to do random operations within the application than is at the database layer.
// Your database stuff
while ($row = $result->fetchRow()) {
$results[] = $row;
}
$firstResult = array_shift($results);
for ($i = 0 ; $i < 3 ; $i++) {
$randomKey = array_rand($results);
$randomResults[] = $results[$randomKey];
}
echo $firstResult;
foreach ($randomResults as $randomResult) {
echo $randomResult;
}
I have the following structure:
Table: products
id, name, sort_order
Let's say I only have 5 products, but I want 20.
How would I loop through to get 20 results?
Additionally, I'll need to start at a specific sort_order. So let's say I have
1,2,3,4,5
and I want to get 20 results and start at 3. It should end up as:
3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,etc.
Any ideas? I'm totally lost.. thank you!
$how_many = 20;
$counter = 0;
$rows = array();
$result = mysql_query("Your query");
while($row == mysql_fetch_row($result)) {
$rows[] = $row;
}
$expanded = array();
for($i = 0; $counter < $how_many; $counter++) {
$expanded[] = $rows[$i];
$i++;
if($i == count($rows)) {
$i = 0;
}
}
And now $expanded is filled with those 5 rows for 4 times.
Edit: and don't forget to adjust $i to your start element. For your example that would mean $i = 2 (third element).
create a table named abc and use this procedure to populate the table
CREATE PROCEDURE `populator`(i INT)
BEGIN
DECLARE existing int;
DECLARE counting int;
DECLARE limitation int default i;
SELECT COUNT(*) INTO existing FROM asd;
theLoop: LOOP
SELECT COUNT(*) INTO counting FROM abc;
IF (existing + counting) > i
THEN SET limitation = i - counting;
END IF;
IF counting >= i
THEN LEAVE theLoop;
ELSE
SET #sql = CONCAT("INSERT INTO abc SELECT id from asd LIMIT ", limitation);
PREPARE s1 FROM #sql;
EXECUTE s1;
DEALLOCATE PREPARE s1;
END IF;
END LOOP theLoop;
END
remember to rename the tables. i used asd as source table and abc as destination table. if you do the concatenation thing right you can even write a procedure that works with temporary tables.
You can do this in MySQL by cheating:
SELECT
t1.id
FROM
products t1
CROSS JOIN products t2
LIMIT
2, 20
Like the others, I'm not 100% sure what you want. You want to show the same products over again until 20 times?