using MYSQL count function to get two columns - php

I am currently using the following query to retrieve data from a database:
SELECT product_Id, COUNT(product_Id) as count
FROM my_sales
GROUP BY product_Id
ORDER BY count DESC
in phpmyadmin it looks like this:
_____________________________________
Product_ID | count
__________________|__________________
12 | 13
13 | 21
14 | 24
The PHP Code im using looks like this:
$res = $connVar->prepare($query); //the query described above
$res->execute();
$res->fetch(PDO::FETCH_ASSOC);
while ( $row = $res->fetch(PDO::FETCH_ASSOC) )
{
$data[] = $row;//return the information from the database as an array
echo $data[0]['product_Id']; //trying to target specific indexes of an associative array :/
echo $data[0]['count'];
}
What really needs to happen is that I can store each row as variables so that I can say, print out in php how much stock is left for a particular product.
Been looking on stackoverflow for around 4 hours now and about to give up. There are a lot of questions available about returning the whole dataset within one variable but thats not what i need.
Any help?

Related

How to add not existing record and return it with zero value in Mysqli

QUERY:
SELECT month(date_created), count(a.ticket_num)
FROM ticket as a
LEFT JOIN user_management as b on b.engineer_id = a.ticket_engineer
WHERE b.tl_id = 'sample_id'
AND year(date_created) = '2019'
GROUP BY extract(year from date_created), extract(month from date_created)
SAMPLE OUTPUT:
month | ticket_num
----------------------
2 | 12
4 | 24
6 | 78
EXPECTED SAMPLE OUTPUT:
month | ticket_num
----------------------
1 | 0
2 | 12
3 | 0
4 | 24
5 | 0
6 | 78
As you can see the above expected output, i'm trying to place all existing month in the first column and set all the count to zero if not existed in the second column. As of now, i only have the query for sorting the ticket count by month that is existed when the ticket is created.
There are different approaches to this problem. One is pure SQL for example.
But I would say a PHP based solution is simpler. Basically you need to get your data into array, then create a loop that outputs the desired months order, and have a condition that sees whether we have a corresponding row in our array and outputs ether the actual data or a zero accordingly.
The only tricky part is to have such an array that would let us check the data availability. For this we have to index it with month numbers. Not a big deal actually
$sql = "SELECT month(date_created), count(a.ticket_num) ...";
$res = $mysqli($sql);
$data = [];
while($row = mysqli_fetch_row($res)) {
$data[$row[0]] = $row[1];
}
Now $data is an array indexed by the month number. The rest is a primitive loop
foreach (range(1,12) as $month) {
echo $data[$month] ?: 0;
}
On a side note I would like to advertise using PDO as opposed to mysqli for your database interactions as this case clearly displays the superiority of the former. Using PDO we can get the indexed array right away, without an explicit loop, thanks to a special fetch mode:
$sql = "SELECT month(date_created), count(a.ticket_num) ...";
$data = $data = $pdo->query($sql)->fetchAll(PDO::FETCH_KEY_PAIR);
That's all!

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

Retriving an array of grouped elements in mysql (+php)

I need i bit of help with this query, so far i have this:
SELECT * FROM coupons WHERE discount_id = '1' AND client_username = 'Zara' GROUP BY winner_id
The table is like this
id client_username winner_id bdate discount_id destroyed
72 zara 1125405534 2012-11-11 03:34:49 4 0
71 zara 1125405534 2012-11-11 03:34:43 1 0
70 zara 1125405534 2012-11-11 03:34:27 1 0
I want to group the result by winner_id (its a unique user id) where discount_id is equal to some value and order by bdate, the think is I need the id bdate and destroyed value of each ocurrence of the user and also count the number of times winner_id appear, so the result needs to be a value (count of how many times winner_id appears), and 3 arrays (discount_id,destroyed,id).. But I have no idea how to retrive this in the way I need. Thanks for any help!
Two basic methods:
aggregate in mysql and "explode" in php
aggregate in PHP
number 1 involves using some aggregate functions in your query, like COUNT() and GROUP_CONCAT():
SELECT count(*) as num_wins, GROUP_CONCAT(discount_id, ',') as discount_ids ...
then in PHP, these GROUP_CONCAT columns can be "exploded" into arrays while looping over the results:
foreach($rows as $row) {
$discount_ids = explode(',', $row['discount_ids']);
// ...
}
number 2 is easier SQL, but uglier PHP. Basically just select all your rows, and then pre-process the results yourself. (I recommend the previous solution)
foreach($rows as $row) {
$results_tree[$row['winner_id']]['num_wins']++;
$results_tree[$row['winner_id']]['discount_ids'][] = $row['discount_id'];
// ...
}

Select rows where column text contains value of an array

I'm building a search function in php/mysql and I'm looking for the right MySql function. My table sort of looks like this:
id | text
--------------------------------------
1 | I like pony's.
2 | Do you like fish?
3 | We like fishes!
I want to search the column 'text' for one of the exact values of an array, for example:
$search_array = array('fish','dogs','cat','panda');
I'm looking for the right MySql function to return only the second row (with the current array). The array can contain hundreds of values.
I have 6000+ rows, growing everyday with +/- 400. I've tried REGEXP but with a large array, it took about 10 seconds before it returned the corresponding rows.
Please help, I'm fighting with this for almost 3 full days now... Thanks in advance!
If the search array is constant, or changes infrequently, I recommend having another two tables, 'tags' and 'tags-text'.
For example, the row with id 2 in your example contains fish, since fish is in our 'tags' table a new record will be placed in a 'tags-text' table. When you are searching with your array, you can search if one of the array components is in the 'tags-text' table, and join the 'text' table and return the text and id and do whatever you need.
Structure of other tables:
'tags' table
id | tags
--------------------------------------
1 | fish
2 | dogs
3 | cats
'tags-text' table
text-id | tags-id
--------------------------------------
2 | 1
Does this help/make sense
Ok I think I've found the easiest solution: let PHP create the mysql query and solve it with WHERE LIKE.
$search_array = array('fish','dogs','cat','panda');
$string = '';
foreach($search_array as $term) {
$string = $string."text LIKE '%".$term."%' AND ";
}
The result of the foreach loop is:
"text LIKE '%fish%' AND LIKE '%dogs%' AND LIKE '%cat%' AND LIKE '%panda%' AND "
Now lets remove the tail of that string and write the query:
$string = substr($string, 0, -5); // removing " AND " at the end of the string
$query = "SELECT * FROM table WHERE $string";
$results = mysql_query($query);
Thanks for the other answers anyway :)
Ok, maybe you should try mixing mysql and php a bit.
Here is the pseudo-code
select 100-1000 rows at one time from db
use strpos to check each element in your array against the text column
if element found
store it
if 2 elements found break the loop
else
continue
Something like this maybe ...
$search_term = implode(",",$search_array);
SELECT * FROM your_table WHERE text IN ($search_term)";

how to find the greatest number from an array

This is the books table on db;
book_ID writer_ID
-------- -----------
1 10
2 10
3 10
4 10
5 10
This is the rates table on the db,
book_ID rate
------- --------
1 4
2 3
2 5
2 1
2 4
3 5
4 2
4 5
4 2
4 4
5 3
now, i have the writer_ID at first, and i have to find all book_ID (connected to that writer_ID) and the average rates of each book_ID from the rates table. finally, i have to find the greatest rate average and its book_ID
this is my code
$query="SELECT * FROM books WHERE seller_id ='$id'";
$result = mysql_query($query);
while ($info = mysql_fetch_array($result)) {
//getaveragerate is the function that returns average of the rates from rates table
$arr = array(ID => $info['book_ID'], average => getaveragerate($info['book_ID']));
}
$greatest_average_and_books_id_number = max($arr); // dont know how to get highest average and its ID together from array
that is my question, sorry but english is not my native language, i am trying my best to explain my problem. sometimes i cant and i just stuck.
thanks for understanding.
Or just let the database do it for you:
SELECT max(fieldname) FROM rates WHERE id='34'
If you are limited as to which functions you can perform (ie using some CRUD class):
SELECT * FROM rates WHERE id='34' ORDER BY id DESC LIMIT 1
You haven't told us what fields from the database will be returned by your query. It also looks like you're filtering (WHERE clause) on key column, which should only return one record. Therefore you can strip out everything you have there and only put:
$greatest_record = 34;
No need for a query at all!
With a little more information on what you're doing and what fields you're expecting:
$query = "SELECT id, rate FROM rates";
$result = mysql_query($query);
$myarray = array();
$greatest_number = 0;
while ($row = mysql_fetch_array($result)) {
myarray[] = $row; // Append the row returned into myarray
if ($row['id'] > $greatest_number) $greatest_number= $row['id'];
}
// Print out all the id's and rates
foreach ($myarray as $row_num => $row) {
print "Row: $row_num - ID: {$row['id']}, Rate: {$row['rate']} <br>";
}
print "Highest ID: $greatest_number";
Note that we maintained what was the greatest number at each row returned from the database, so we didn't have to loop through the $myarray again. Minor optimization that could be a huge optimization if you have tens of thousands of rows or more.
This solution is on the basis that you actually need to use the ID and RATE fields from the database later on, but want to know what the largest ID is now. Anyone, feel free to edit my answer if you think there's a better way of getting the greatest_number from the $myarray after it's generated.
Update:
You're going to need several queries to accomplish your task then.
The first will give you the average rate per book:
SELECT
book_id,
avg(rate) as average_rate
FROM Rates
GROUP BY book_id
The second will give you the max average rate:
SELECT
max(averages.average_rate),
averages.book_id
FROM (
SELECT
book_id,
avg(rate) as average_rate
FROM Rates
GROUP BY book_id
)
as averages
WHERE averages.average_rate = max(averages.average_rate)
This will give you a list of books for a given writer:
SELECT book_id
FROM Books
WHERE writer_id = $some_id
Don't try to do everything in one query. Mixing all those requirements into one query will not work how you want it to, unless you don't mind many very near duplicate rows.
I hope you can use this update to answer the question you have. These SQL queries will give you the information you need, but you'll still need to build your data structures in PHP if you need to use this data some how. I'm sure you can figure out how to do that.

Categories