PHP While: prevent looping rows where one field is identical to another - php

I'm using a while loop to get some data from my database, however the problem I have is that it's looping everything inside it (as expected from the start) but now I wonder if it's possible for it to search for duplicated, and skip those? Depending on if a field is identical.
Let's say 3 rows are being looped, everyone have the field "number" but only the first 2 rows has the same value in the field "number". I want it to only loop the first one, and then skip the 2nd one as it already has the same value in the "number" field as the previous one. Is it possible?
$q = $database->query("SELECT * FROM table1 ORDER BY id DESC LIMIT 7");
while($f = $q->fetch_array()) {
echo $f["number"] . "<br />";
}

you can avoid duplicated elements on mysql by adding the DISTINCT keyword after select
SELECT DISTINCT id,nom,prenom FROM matable

Related

php pg_fetch_array only show first result

i query to check if a point(input) is intersect with polygons in php:
$sql1="SELECT ST_intersects((ST_SetSRID( ST_Point($startlng, $startlat),4326))
, zona_bahaya.geom) as intersek
FROM zona_bahaya";
$query1 = pg_query($conn,$sql1);
$check_location = pg_fetch_array($query1);
if (in_array('t',$check_location)) {
dosemthing1;}
else {dosomething2;}
it's work peroperly before i update the data
after data updated, it's only show the first row when i check the pg_fetch_array result. here is the result {"0":"f","intersek":"f"} .
i try to check from pgadmin and it's can show 8 result (1 true(intersected) and 7 false(not intersect)) using updated data with this query:
SELECT ST_intersects((ST_SetSRID( ST_Point(110.18898065505843, -7.9634510320131175),4326))
, zona_bahaya.geom) as intersek
FROM zona_bahaya;
to solve it, i order the query result descended so the 'true' gonna be the first like this:
order by intersek desc
anybody can help me to findout way it just only show the first row???
here some geom from STAsText(zonabahaya.geom) not all of them : MULTIPOLYGON(((110.790892426072 -8.19307615541514,110.791999687385 -8.19318330973567,110.794393723931 -8.1927980624753,110.794586347561 -8.19205508561603,110.795329324421 -8.19120203811094,110.796540101525 -8.19023891996003,110.797503219676 -8.18933083713203,110.798576408472 -8.18919324882476,110.79929186767 -8.18957849608512,110.800337538805 -8.19059664955894,110.800585197758 -8.19150473238694,110.80022746816 -8.19238529755349,110.799787185576 -8.19290813312112,110.799589319279 -8.19300706626968,110.798788231202 -8.19299429992581,110.798537293576 -8.19311976873883,110.79850269889 -8.1933090511224,110.798620939451 -8.19433728092441)))
In order to filter only the records that intersect you have to use ST_Intersects in the WHERE clause:
SELECT *
FROM zona_bahaya
WHERE ST_Intersects(ST_SetSRID(ST_Point(110.18, -7.96),4326),zona_bahaya.geom);
Since you're dealing with points and polygons, perhaps you should take a look also at ST_Contains.
In case you want to fetch only the first row you must set a limit in your query - either using LIMIT 1 or FETCH FIRST ROW ONLY -, but it would only make sense combined with a ORDER BY, e.g.
SELECT *
FROM zona_bahaya
JOIN points ON ST_Intersects(points.geom,zona_bahaya.geom)
ORDER BY gid
FETCH FIRST ROW ONLY;
Demo: db<>fiddle

How to select one row from multiple which are with same column name in mysql?

I have a table with with columns name:
id
message
sender
chat_id
I want to get one row from number of rows with same chat_id ,during while loop fetch.
What Will be the MySQL Query
If you only want one row, one of those columns needs to have unique data so you can add it to the WHERE clause
SELECT id,message,sender,chat_id from information WHERE id=2 for example.
SELECT id,message,sender,chat_id from information WHERE chat_id=5 AND sender='mark'
OR during the while loop, match the column and grab whatever you want from it.
But again, it needs to be a unique combination of data otherwise it'll be overwritten by the previous.
while($row = $result->fetch_assoc()){
if($row['sender'] == 'mark' && $row['chat_id'] == '5'){
$thisIsMyRow = $row['id'];
}
Please could you explain more? What is it you're trying to achieve?
Say this is your query:
SELECT id,message,sender,chat_id from messages WHERE chat_id=1
You may have 200 rows that match that query. To return just one result, you can do a couple of things.
If you want the latest message, you can do this:
SELECT id,message,sender,chat_id from messages WHERE chat_id=1 ORDER BY id DESC LIMIT 1
another example, latest 5 messages
SELECT id,message,sender,chat_id from messages WHERE chat_id=1 ORDER BY id DESC LIMIT 0,5
In addition when you take it back into PHP, rather than going through the loop, you can JUST do this:
$row = $result->fetch_assoc()
As our query is only returning 1 row, you don't need to loop through. You can do this when your query returns multiple results - but it'd be better to optimise your query.
I can advise better if you are able to elaborate.
while($row = $result->fetch_assoc()){
$query = "SELECT id, message, sender,chat_id FROM messages WHERE Y = X AND Z = $K LIMIT 1";
}
replace the WHERE part with whatever column you want

Query returning additional empty variable

I'm running into some weird behaviour when calling values with SQL.
$result = mysqli_query($conn,"SELECT DISTINCT value FROM table ORDER BY value ASC");
while($row[] = mysqli_fetch_array($result));
$maxcat = count($row);
There are 8 unique values in my table, yet $maxcat returns "9". Am I missing something? I'm using the information to populate a list of categories. I knew I'd have to subtract one from maxcat to allow for $row[0], but I'm having to subtract two to make up for this empty value that won't get lost.
for ($i=0; $i<=($maxcat-2); $i++)
Cheers!
Thanks #scrowler & #faintsignal! Using mysqli_num_row() rather than count() is exactly what I needed. Functioning code below.
$result = mysqli_query($conn,"SELECT DISTINCT value FROM table ORDER BY value ASC");
$maxcat = mysqli_num_rows($result);
while($row[] = mysqli_fetch_array($result));
The while condition gets evaluated once for every row in your query result, plus one additional time to detect that there are no more rows left. So if you have 8 rows in your result, the while condition is evaluated 8 + 1 = 9 times. Hence you add 9 entries to your array $row, the final entry having the value NULL.
Note, if your while loop had a body, that body would only be iterated 8 times because the 9th time the condition would evaluate to false.
As #scrowler pointed out, if you just want to count the number of rows in the result, you can simply use mysqli_num_rows.

mysql within Joomla next and previous SQL statement within orderby

I know things are escaped incorrectly, but I am trying to write a previous/next query to get the next id and previous id within an order, but my output does not match the phpmyadmin sorting, which it should. I just have the 'next' written, and would write the previous with reverse conditions. This query seems to give me the next highest ID value number within the order...I need the next or previous in the order index...can anyone help?
$db = JFactory::getDBO();
$query = "SELECT image_id FROM #__jxgallery_images WHERE image_id >".$currentid."' ORDER BY '".$ordering." ".$direction." LIMIT 1";
// Executes the current SQL query string.
$db->setQuery($query);
// returns the array of database objects
$list = $db->loadObjectList();
// create the list of ids
foreach ($list as $item) {
$next = $item->image_id;
echo $next.'<br/>';
}
echo 'The next ID in this sort state is '.$next.'<br />';
?>
This is phpmyadmin and it is right...
SELECT * FROM `jos_jxgallery_images`
ORDER BY `jos_jxgallery_images`.`hits` DESC
LIMIT 0 , 30
I have now matched this query in my code to get the same results. My variables fill in the ($ordering) 'hits' field and the 'desc' ($direction) within my clause. That works fine. The image_ids and hits aren't special...just numbers. When hits are ordered, the image_ids are resored to match. I don't need the next value of image_id as to what is in the field. I need the next row or previous row, regardless of value, based on the current image_id I plugin.
These are actual image_ids LIMIT 5, and these are Ordered by the hits field Descending:
52791
52801
52781
52771
52581`
Now if the current image I'm looking at has an id of 52791, then previous should be nothing and next should be 52801. What my query is doing I think is giving me an image_id of a higher valued number as 'next' because that is the next highest VALUED image_id, not the next row. I can see why in the query, I am asking for greater than...but I just need the next row
I think the problem is with your WHERE condition: WHERE image_id >".$currentid."'
If I understand what you're trying to do, one way to do it is this:
$query = "SELECT image_id FROM `#__jxgallery_images` ORDER BY ".$ordering." ".$direction." LIMIT 2";
$db->setQuery($query);
$list = $db->loadObjectList();
$next_item = $list[1]->image_id;
Notice that the WHERE condition is removed from the query, and I also changed LIMIT 1 to LIMIT 2. This way, the query basically returns your top value and the one with the next highest "hits" value.
I hope this helps.

Checking if a value is in the db many times

I have a table A, with just two columns: 'id' and 'probably'. I need to go over a long list of ids, and determine for each one whether he is in A and has probability of '1'. What is the best way to do it?
I figured that it would be best to have 1 big query from A in the beginning of the script, and after that when I loop each id, I check the first query. but than i realized I don't know how to do that (efficiently). I mean, is there anyway to load all results from the first query to one array and than do in_array() check? I should mention that the first query should had few results, under 10 (while table A can be very large).
The other solution is doing a separate query in A for each id while I loop them. But this seems not very efficient...
Any ideas?
If you have the initial list of ids in array, you can use the php implode function like this:
$query = "select id
from A
where id in (".implode (',', $listOfIds).")
and probability = 1";
Now you pass the string as first parameter of mysql_query and receive the list of ids with probability = 1 that are within your initial list.
// $skip the amount of results you wish to skip over
// $limit the max amount of results you wish to return
function returnLimitedResultsFromTable($skip=0, $limit=10) {
// build the query
$query = "SELECT `id` FROM `A` WHERE `probability`=1 LIMIT $skip, $limit";
// store the result of the query
$result = mysql_query($query);
// if the query returned rows
if (mysql_num_rows($result) > 0) {
// while there are rows in $result
while ($row = mysql_fetch_assoc($result)) {
// populate results array with each row as an associative array
$results[] = $row;
}
return $results;
} else {
return false;
}
}
for each time you call this function you would need to increment skip by ten in order to retrieve the next ten results.
Then to use the values in the $results array (for example to print them):
foreach ($results as $key => $value) {
print "$key => $value <br/>";
}
Build a comma separated list with your ids and run a query like
SELECT id
FROM A
WHERE id IN (id1, id2, id3, ... idn)
AND probability = 1;
Your first solution proposal states that:
You will query the table A, probabyly using limit clause since A is a table with large data.
You will place the retrieved data in an array.
You will iterate through the array to look for the id's with probability of '1'.
You will repeat the first three steps several times until table A is iterated fully.
That is very inefficient!
Algorithm described above would require lots of database access and unneccessary memory (for the temporary array). Instead, just use a select statement with 'WHERE' clause and process with the data you want.
You need a query like the following I suppose:
SELECT id, probably FROM A WHERE A.probably = 1
If i understood you correctly, you should filter in the SQL query
SELECT * FROM A WHERE A.probably = 1

Categories