PHP fetch_array/sql without sorting values - php

SQL:
SELECT question,alt_1,alt_2,alt_3,alt_4 FROM questions WHERE id IN ('12','2','32','23')
PHP:
while ($questions = mysql_fetch_array($game)){
echo "$questions[question]";
}
I want the rows to be printed in the order the values are sent to sql: 12 - 2 - 32 - 23.
But fetch_array/sql(?) seems to sort the values so the order becomes the following: 2 - 12 - 23 - 32 (starts with the lowest number..)
Is there any way to stop the array from being sorted by numbers!?

USE FIND_IN_SET
SELECT question,alt_1,alt_2,alt_3,alt_4
FROM questions
WHERE id IN ('12','2','32','23')
ORDER BY FIND_IN_SET(id, '12,2,32,23')
Note FIND_IN_SET(id, '12,2,32,23') 12,2 without space
FIND_IN_SET(field, 'val1,val2')

Try yhis,
" ORDER BY FIELD(id'12','2','32','23')"
SQL: "SELECT question,alt_1,alt_2,alt_3,alt_4 FROM questions WHERE id IN
('12','2','32','23') ORDER BY FIELD(id'12','2','32','23')"
while($questions = mysql_fetch_array($game)){
echo "$questions[question]";
}

Related

Return list of member_number count in table

Consider the following table
I need to return a list in descending order with the count of the member_nr's who is appearing the most frequent in the table where tournament = 'EPL' AND ROUND = '12'
EXAMPLE
The script should return the following results:
I thought about the problem and my logic for the problem reads like this
STEP1: GET member_nr one by one
$sql = "SELECT DISTINCT *
FROM winners
WHERE tournament='$tour' AND round='$round'";
LOOP(){ //get 1 member number
$mem_nr = ['mem_nr']; //assign mem_nr to variable
STEP2: GET the count(number of times) ^ABOVE^ member number appears in table
"$sql="SELECT *, count(member_nr) as nrWins
FROM winners
where member_nr ='$memNr' and tournament='$tournament' AND round='$round'";"
LOOP(){//get count
STEP 3: DISPLAY DATA
echo $row=['nrWins'] //Display Number Wins
echo $memNr
}//END LOOP
}//END LOOP
My Problem:
The above does not seem very efficient to me, im looking for the shortest most efficient way to return the count of member numbers in table above, any ideas / suggestions are welcomed
Try something like this:
SELECT *, COUNT(*) AS `wins`
FROM `winners`
WHERE `tournament` = '$tournament'
AND `round` = '$round'
GROUP BY `member_nr`
ORDER BY `wins` DESC
select tournament,round,member_nr,count(*)
from table
where tournament = 'EPL'
and round = 12
group by tournament,round,member_nr
order by count(*) desc

How to add together the values in an array from MySQL query

I'm trying to add together values generated from a MySQL query but the total I'm getting doesn't seem to add up. Here's my code:
$top_score = mysql_fetch_array(mysql_query("SELECT 1ET FROM scoring_data WHERE
Competition='$competition' AND Club='$row[Club]' AND Team='$row[Team]' ORDER BY
1ET DESC LIMIT 0, 3"));
echo (array_sum($top_score)/10) ;
I have two values entered into 1ET for that specific query (competition, club and team): 6 and 3. The total I should get is 9, but the total is coming out as 12...
Any suggestions gratefully received!
The array isn't structured how you expect it to be:
print_r($top_score);
Maybe do it in the query:
SELECT SUM(1ET)/10 AS top_score FROM scoring_data WHERE
Competition='$competition' AND Club='{$row['Club']}' AND Team='{$row['Team']}'
ORDER BY 1ET DESC LIMIT 0, 3

Find Duplicate Rows/Records from Table

Here is my table structure,
Im try run query
$sql = mysql_query("SELECT content,niche, COUNT(content) TotalCount FROM table_name GROUP by content HAVING COUNT(content)>=2");
I i think is give me corect result, but have problem to list result with php and make delete button to delete one of duplicated rows
Im get result in php
Content ID - Niche ID - TotalCount
208 - 2 - 2
210 - 32 - 3
But result should be
Content ID - Niche ID - TotalCount
208 - 2 - 2
208 - 2 - 2
210 - 32 - 3
210 - 32 - 3
210 - 32 - 3
im try result display with php
while($row = mysql_fetch_assoc($sql)) {
$array[] = $row;
}
foreach($array as $row) {
echo $row['content']." - ".$row['niche']." - ".$row['TotalCount']."<br>";
}
GROUP BY will collapse the results on the field you're grouping, in this case content - hence why you only see two results.
If you want to keep the GROUP BY technique, you can also use GROUP_CONCAT(niche) to pull a comma-separated list of each niche for a given content value:
SELECT
content,
GROUP_CONCAT(niche) AS niche,
COUNT(content) TotalCount
FROM
table_name
GROUP BY
content
HAVING
COUNT(content)>=2;
You can then use PHP's explode(',', $row['niche']) to get each distinct value and then use those to determine which one you want to delete.
foreach($array as $row) {
$niches = explode(',', $row['niche']);
foreach ($niches as $niche) {
echo $row['content'] . " - " . $niche . " - " . $row['TotalCount'] . "<br />";
}
}
I think this is what you're asking for, all duplicate rows (with row_id) and how many times they are duplicated;
SELECT a.row_id, a.content, a.niche, cnt
FROM table_name a
JOIN (
SELECT MIN(row_id) m, COUNT(*) cnt, niche,content
FROM table_name
GROUP BY content,niche
HAVING COUNT(*)>1
) b
ON a.niche=b.niche
AND a.content=b.content
An SQLfiddle to test with.
Make the following change in sql:
$sql = mysql_query("SELECT content,niche, COUNT(content) TotalCount FROM table_name HAVING COUNT(content)>=2");

SQL query results returned, even if exact match not found

I hope this question isn't redundant. What I am trying to accomplish is have a user select a bunch of checkboxes on a page and return the closest matching records if there are no matching rows. For example:
A person checks off [x]Apples [x]Oranges [x]Pears [x]Bananas
But the table looks like this:
Apples Oranges Pears Bananas
1 1 1 null
1 1 null 1
1 1 null null
(Obviously I missed the id column here, but you get the point I think.) So, the desired result is to have those three rows still be returned in order of most matches, so pretty much the order they are in now. I'm just not sure what the best approach to take on something like this. I've considered a full text search, the levenshtein function, but I really like the idea of returning the exact match if it exists. No need for you to go at length with code if not needed. I'm just hoping to be sent in the right direction. I HAVE seen other questions sort of like this, but I still am unsure about which way to go.
Thanks!
Write a query that adds up the number of columns that matched, and sorts the rows by this total. E.g.
SELECT *
FROM mytable
ORDER BY COALESCE(Apples, 0) = $apples + COALESCE(Oranges, 0) = $oranges + ... DESC
It's easy to sort by a score...
SELECT fb.ID, fb.Apples, fb.Oranges, fb.Pears, fb.Bananas
FROM FruitBasket fb
ORDER BY
CASE WHEN #Apples = fb.Apples THEN 1 ELSE 0 END
+ CASE WHEN #Oranges = fb.Oranges THEN 1 ELSE 0 END
+ CASE WHEN #Pears = fb.Pears THEN 1 ELSE 0 END
+ CASE WHEN #Bananas = fb.Bananas THEN 1 ELSE 0 END
DESC, ID
However, this leads to a table-scan (even with TOP). The last record may be a better match than the records found so far, so every record must be read.
You could consider a tagging system, like this
Content --< ContentTag >-- Tag
Which would be queried this way:
SELECT ContentID
FROM ContentTag
WHERE TagID in (334, 338, 342)
GROUP BY ContentID
ORDER BY COUNT(DISTINCT TagID) desc
An index on ContentTag.TagId would be used by this query.
This is fairly simple, but you can just use IFNULL() (MySQL, or your DB's equivalent) to return a sum of matches and use that in your ORDER BY
// columns and weighting score
$types = array("oranges"=>1, "apples"=>1, "bananas"=>1, "pears"=>1);
$where = array();
// loop through the columns
foreach ($types as $key=>&$weight){
// if there is a match in $_REQUEST at it to $where and increase the weight
if (isset($_REQUEST[$key])){
$where[] = $key . " = 1";
$weight = 2;
}
}
// build the WHERE clause
$where_str = (count($where)>0)? "WHERE " . implode(" OR ", $where) : "";
// build the SQL - non-null matches from the WHERE will be weighted higher
$sql = "SELECT apples, oranges, pears, bananas, ";
foreach ($types as $key=>$weight){
$sql .= "IFNULL({$key}, 0, {$weight}) + ";
}
$sql .= "0 AS score FROM `table` {$where_str} ORDER BY score DESC";
Assuming that "oranges" and "apples" are selection, your SQL will be:
SELECT apples, oranges, pears, bananas,
IFNULL(apples, 0, 2) + IFNULL(oranges, 0, 2) + IFNULL(pears, 0, 1) + IFNULL(bananas, 0, 1) + 0 AS score
FROM `table`
WHERE oranges = 1 OR apples = 1
ORDER BY score DESC
Order descending by the sum of checkbox/data matches
SELECT * FROM table
ORDER BY (COALESE(Apple,0) * #apple) + (COALESE(Orange,0) * #orange) ..... DESC
where #apple / #orange represents users selection: 1 = checked, 0 = unchecked

mysql order by issue

if i have a query like :
SELECT * FROM table WHERE id IN (3,6,1,8,9);
this array of the ids is build in php dynamically ,
and the order is important to me.
$my_array = array (3,6,1,8,9) ;
how can i sort the results by the order by which the elements appear in my array ?
its possible to do it in MYSQL query,
or i must to order it after via php ?
You can order by a value derived from a column. You can use a CASE operator to specify the order:
SELECT * FROM table
WHERE id IN (3,6,1,8,9)
ORDER BY CASE id WHEN 3 THEN 1
WHEN 6 THEN 2
WHEN 1 THEN 3
WHEN 8 THEN 4
WHEN 9 THEN 5
END
I haven't tested but this PHP solution should work:
<?php
$my_array = array (3,6,1,8,9) ;
$sql = 'SELECT * FROM table WHERE id IN (3,6,1,8,9)';
$sql .= "\nORDER BY CASE id\n";
foreach($my_array as $k => $v){
$sql .= 'WHEN ' . $v . ' THEN ' . $k . "\n";
}
$sql .= 'END ';
echo $sql;
?>
This generates the following SQL code:
SELECT * FROM table WHERE id IN (3,6,1,8,9)
ORDER BY CASE id
WHEN 3 THEN 0
WHEN 6 THEN 1
WHEN 1 THEN 2
WHEN 8 THEN 3
WHEN 9 THEN 4
END
If you must do it this way you'll have to manipulate the data in PHP. MySQL can only order by natural orderings ascending or descending.
Got to question though - why do you need the data returned in this very specific order? There may be an easier solution to your problem by re-jigging something further up in the code.
SELECT * FROM table WHERE id IN (3,6,1,8,9) ORDER BY FIELD(id,3,6,1,8,9);
You can load the results into an array with IDs as indexes:
while ($row = mysql_fetch_array($l)) $items[$row['id']] = $row;
and then simply iterate it in your order
foreach ($my_array as $id) { $current_row = $items[$id]; ... }

Categories