Select Random yet distinct rows from table - MySQL - php

I have a table with various categories, and multiple entries for each category.
Word | Category
------------------
Apple | Food
Orange | Food
Grapes | Food
Mango | Food
I wish to retrieve 3 random rows for the category 'food', for which I run the following query,
$query = "SELECT * FROM table WHERE category='food' ORDER BY RAND() LIMIT 3"
$fetch_row = mysqli_query($db_connect, $query);
while ($row = mysqli_fetch_array($fetch_row)) {
array_push($words, $row['word']);
}
However, when I print the contents of the array $words, they tend to repeat sometimes (not on all runs), for example;
Apple, Orange, Apple
i.e. Its not always unique. I want to select random, yet unique words for a given category. What am I doing wrong? I've tried going through other related answers, but I keep messing something up. I've also tried the following query;
SELECT * FROM table WHERE category='food' GROUP BY category ORDER BY RAND() LIMIT 3
But this still gives repetitions occasionally.

Since word column have same values, do GROUP BY word like below:-
SELECT * FROM table WHERE category='food' GROUP BY word LIMIT 3

Related

Retrieve total amounts of rows containing strings

I have a table in MySQL, with 5(sort of) possible values in the column 'type'... I say sort of because the data type is 'set' and 1 type has a subcategory... It's for a type of property, so the possible types are retail, office, hospitality, industrial, residential(multi family), residential(single family).
I'm attempting to paginate the results and I need to know how many pages each should have. So I need a query that tells me how many of each type are in the table, the user can select residential as a category, or single, multi as subcategories.
I can't figure out how to do a query that tells me how many of each there are, or how to retrieve those numbers as variables I can use to divide be items per page.
id | type
-----------------------
1 | office
2 | residential,single
3 | industrial
4 | residential,multi
5 | retail
6 | office
7 | hospitality
8 | residential,single
etc....
so if this was the data, I would need to get:
$office = 2
$residential = 3
$industrial = 1
$single = 2
etc...
Use array_count_values() function
Check the link http://php.net/manual/en/function.array-count-values.php
From their website http://php.net/manual/en/function.array-count-values.php;
and Try this code
<?php
$query= // Run your select query.
$result= mysqli_query($link, $query);
//Run the while loop
while($row= mysqli_fetch_array($result))
{
$array[]=$row['Column_Name'];//Store the result in array
}
$count = array_count_values($array);//Use array count
print_r($count);//See the result
Or if you see The out put the way you want
Run Foreach loop on the $count array
foreach($count as $key => $value) {
//Get the out put From new array
echo $value .' '. $key.'<br/>' ;
}
A count and group by should do the trick;
SELECT id, type, COUNT(*) as count
FROM mytable
GROUP By id

Only get one occurance of a table row in mysql php based on id

I have a table that looks like this
id | itemID | catID | Title
----------------------------------------------------------------------------
0 3 4 Hello
1 3 6 Hello
2 4 4 Yo
3 4 8 Yo
4 5 2 Hi
5 1 3 What
I want to do a MySQL PHP Select that only gets one occurrence of the itemID. As you can see they are the same item, just in different categories.
This is what I tried
SELECT * FROM Table GROUP BY itemID
That didn't seem to work, it still just shows duplicates.
Is this what you are looking for? http://www.sqlfiddle.com/#!2/5ba87/1
select itemID, Title from test group by itemID;
As far as MySQL is concerned, the data is all unique, since you want all of the columns. You have to be more specific.
Do you just want the itemID (or other column)? Then say so:
select [column] from Table GROUP BY itemID
Do you want the last entry of a particular item ID? Then say that:
select * from Table where itemID = 1 ORDER BY id DESC
Or the first one?
select * from Table where itemID = 1 ORDER BY id
If none of these are what you want, then you probably need to restructure your tables. It looks like you want different categories for your items. If so, then you'll want to split them out into a new join table, because you have a many-to-many relationship between Items and Categories. I recommend reading up on database normalization, so you're not duplicating data (such as you are with the titles).
If you want everything for the distinct itemIDs, you could certainly take a long route by doing one selection of all of the distinct itemIDs, then doing a series of selections based on the first query's results.
select distinct(`itemID`) from Table
Then in your PHP code, do something like this:
while ($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
$itemID = $row['itemID'];
$sql2 ="SELECT * FROM Table WHERE 1 and `itemID`=\"$itemID\" limit 1";
$result2 = #mysql_query($sql2, $connection);
while ($row2 = mysql_fetch_array($result2))
{
$id = $row2['id'];
$itemID = $row2['itemID'];
$catID = $row2['catID'];
$Title = $row2['Title'];
}
}

Collect values from DB, group matching values, count it and use in other code

This is what my customers_basket table looks like:
customers_id | products_id | basket_quantity
3 | 56:3121fefbe6043d6fc12e3b3de2c8fc38 | 3
3 | 56:fb4c9278fcfe6225b58c06711a7e62ef | 1
3 | 56:8e334fce09556108f5416e27154b6c27 | 1
3 | 52:f3b9f38e4ddd18035bc04cd264b0f052 | 1
This is the query I'm using:
$products_in_cart_query = "SELECT products_id FROM customers_basket WHERE customers_id = " . $_SESSION['customer_id'] ."";
$products_in_cart = $db->Execute($products_in_cart_query);
$products_in_cart_model = $products_in_cart->fields['products_id'];
$products_in_cart_model = substr($products_in_cart_model, 0, strpos($products_in_cart_model, ":"));
The end result I get is 56,56,56,52
First of all, how do I use the first line's quantity field? I'd need to list that products_id 3 times since quantity is 3. Therefore, the end result needs to be: 56,56,56,56,56,52
or, for easier understanding (56,56,56),56,56,52
And second, how do I count how many same values I have? In this case, I have 5x56 and 1x52. I need to use those counts in my further calculation.
EDIT: further calculations explained
I need to know how many of each product_id I have and then run something like this:
foreach(product_id) {
$shipping_cost += FIXED_VALUE * basket_qty;
}
To get the basket quantity, you have to select it. It would be best if the first portion of the product ID was stored in a separate column, rather than having to do messy operations like substringing.
Query 1: 2-character codes and corresponding quantities
SELECT SUBSTR(products_id, 1, 2) AS product_code, basket_quantity
FROM Customers_Basket
WHERE customers_id = 3;
Query 2: 2-character codes and summed quantities
SELECT product_code, SUM(basket_quantity) AS total_quantity
FROM (SELECT SUBSTR(products_id, 1, 2) AS product_code, basket_quantity
FROM Customers_Basket
WHERE customers_id = 3
)
GROUP BY product_code;
If you really, really, really desperately want 3 rows of data for the product ID 56:3121fefbe6043d6fc12e3b3de2c8fc38, then you have to know ways to generate rows. They're truly painful in the absence of convenient SQL support (so much so, that you'd do better to select a row in PHP with the quantity and then generate the appropriate number of rows in your array in the client-side (PHP) code). I'm going to assume that some variation on these queries will get you the information you want.

sql statement to alphabetize and count

Here is the mySQL I got
id terms
1 a
2 c
3 a
4 b
5 b
6 a
7 a
8 b
9 b
10 b
I want to get an alphabetized list sorted by count as follows
terms count
a 4
b 5
c 1
What mySQL statement do I need for that?
I believe something like this will work:
SELECT terms, COUNT( id) AS count
FROM table
GROUP BY terms
ORDER BY terms DESC
Read : GROUP BY (Transact-SQL)
Groups a selected set of rows into a set of summary rows by the values of one or more columns or expressions in SQL. One row is returned for each group. Aggregate functions in the SELECT clause list provide information about each group instead of individual rows.
You just need to apply group by clause for getting result
select terms, count (id) as count from table
group by terms
order by terms
I had a very similar need for a used record store to display artists in stock alphabetically with their count in parenthesis e.g.:
Smokey Robinson and The Miracles (2) | Sonic Youth (2) | Spoon (3) | Steely Dan (1) | Stevie Wonder (2) | Sufjan Stevens (1) |
Note that I used SELECT DISTINCT when pulling from my table "records". Here are the relevant code snippets:
//QUERY
$arttool = mysql_query("SELECT DISTINCT * FROM records GROUP BY artist ORDER BY artist ASC");
//OUTPUT LOOP START
while($row = mysql_fetch_array($arttool)){
//CAPTURE ARTIST IN CURRENT LOOP POSITION
$current=$row['Artist'];
//CAPTURING THE NUMBER OF ALBUMS IN STOCK BY CURRENT ARTIST
$artcount = mysql_num_rows(mysql_query("SELECT * FROM records WHERE artist = '$current'"));
//ECHO OUT.
echo $current . "($artcount)";
The actual code in my site is more complicated, but this is the bare bones of it. Hope that helps...

Counting rows in MySQL (highscore)

I've created a game with a highscore table in MySQL.
I have a "My scores" button that needs to retrieve the users scores, e.g.:
10. John 395
42. John 340
90. John 10
How should I go out retrieving the rank (10th, 42th, 90th) of each score of the user?
I could pull all the scores from the database and iterate through them but that doesn't seem like a good solution.
Let me try to expand:
I retrieve all MY scores from the database. E.g. 10 scores. I want to display these 10 scores however I won't know what the rank of these scores is compared to the other scores in my database! (10th, 16th, etc) ..Hope that makes more sense...
Thanks
For the position in the total list you either need to build up a list every time you want this overview, or use a stored procedure to build a list for a given moment. You could 'cache' a list on a given interval. Or maybe update a list when some one played a game that would change the top 100.
As #WhiteElephant suggested, you'd be making the table every time you want the data.
#stefandoorn suggest to not use the optimized count of sql, i think this is not efficient enough for these kind of computations.
A simple SQL query would do it for you. For example, if you want the 10th score, you could use:
SELECT name, score FROM highscores ORDER BY score DESC LIMIT 1 OFFSET 9
The offset will always be the position required - 1.
If you want to have the associated rank as a column beside the score, you could do the following:
SELECT #rownum:=#rownum+1 position, name, score FROM (SELECT #rownum:=0) r, highscores ORDER BY score DESC
This doesn't work with an offset (the position number will always start at 1). The result would be something like the following:
+----------+-------------+-------+
| position | name | score |
+----------+-------------+-------+
| 1 | Player 1 | 27681 |
| 2 | Player 2 | 14982 |
+----------+-------------+-------+
But I think the best solution is to just loop through the returned values with an index and use the index to keep track of the position.
SELECT
id, name, score,(select count(*) FROM highscores AS higherscores WHERE higherscores.score>currentscores.score)+1 AS rank
FROM
highscores AS currentscores
WHERE name="john"
;
Just use ORDER BYscoreDESC in the end of your query to sort them in reversed order (from high to low). When iterating and showing it in PHP you can use a count:
Query e.g.: SELECT * FROM scores ORDER BY score DESC
$count = 1;
$sql = 'SELECT * FROM scores ORDER BY score DESC';
$result = mysql_query($sql) or die(mysql_error());
while($fetch = mysql_fetch_object($result)) {
echo $count . ' ' . $fetch->score . '<br />';
$count++;
}

Categories