How to count row by using GROUP mysql bind_param ?
Table : check
.
__________________________
| id | product_id | user |
| 1 | 123 | test |
| 2 | 456 | test |
| 3 | 456 | test |
| 4 | 123 | test |
| 5 | 789 | test |
and this is my code
<?PHP
$username = "test";
$sql = 'SELECT COUNT(*) FROM check WHERE user = ? GROUP BY product_id';
$statement = $db_mysqli->prepare($sql);
$statement->bind_param('s', $username);
$statement->execute();
$result = $statement->get_result();
$row = $result->fetch_row();
$all_product = $row[0];
echo $all_product;
?>
When I test code it's show 5 I want to know how can I do for show 3 group by product_id
You need to change your SQL query.
SELECT COUNT(DISTINCT PRODUCT_ID) FROM check WHERE user = ?
this will produce a result of 3
If you wanted one row for each product, then you would do this:
SELECT product_id, COUNT(*) AS c FROM check WHERE user = ? GROUP BY product_id
which would look like this:
| product_id | c |
| 123 | 2 |
| 456 | 2 |
| 789 | 1 |
Try this query.
$statement=$mysqli->prepare("SELECT user,COUNT(*) FROM check GROUP BY product_id");
I hope it will help you.
you can use one of these three queries as per your need. It will give you results as shown below.
To get the total of rows with distinct product_id present in table-:
SELECT COUNT(DISTINCT product_id) FROM check;
Result-:
COUNT(DISTINCT product_id)
3
To get the rows with distinct product_id row-:
SELECT COUNT(DISTINCT product_id) FROM check GROUP BY product_id;
Result-:
COUNT(DISTINCT product_id)
1
1
1
To get the row with distinct product_id with the count number of duplicate product_id present in the table -:
SELECT COUNT(product_id) FROM check GROUP BY product_id
Result-:
COUNT(product_id)
2
2
1
Related
I have three tables :
mls_category
points_martix
mls_entry
My first table (mls_category) is like below:
*--------------------------------*
| cat_no | store_id | cat_value |
*--------------------------------*
| 10 | 101 | 1 |
| 11 | 101 | 4 |
*--------------------------------*
My second table (points_martix) is like below:
*----------------------------------------------------*
| pm_no | store_id | value_per_point | max_distance |
*----------------------------------------------------*
| 1 | 101 | 1 | 10 |
| 2 | 101 | 2 | 50 |
| 3 | 101 | 3 | 80 |
*----------------------------------------------------*
My third table (mls_entry) is like below:
*-------------------------------------------*
| user_id | category | distance | status |
*-------------------------------------------*
| 1 | 10 | 20 | approved |
| 1 | 10 | 30 | approved |
| 1 | 11 | 40 | approved |
*-------------------------------------------*
I am using the following query to show the sum of distance with some condition:
SELECT SUM(t1.totald/c.cat_value)
AS total_distance
FROM mls_category c
JOIN
(SELECT SUM(distance) totald, user_id, category
FROM mls_entry
WHERE user_id = 1
AND status = 'approved'
GROUP BY user_id, category) t1
ON c.cat_no = t1.category
This gives me sum 60 as total_distance, that is correct which I wanted.
Now, I want to include the third table (points_matrix) and want to compare my sum(60) is less than or equal to 80(max_distance) then my new value would be 60*3=180.
So, suppose my sum comes 10 then my new value will be 10*1=10 and if my sum comes 25 then my new value will be according to point matrix 25*2=50.
Yon can using MIN() to calculate what value_per_point you need, and the whole sql is like this:
SELECT MIN(b.value_per_point) * d.total_distance FROM points_matrix b
JOIN
(
SELECT store_id, sum(t1.totald/c.cat_value) as total_distance FROM mls_category c
JOIN
(
SELECT SUM(distance) totald, user_id, category FROM mls_entry
WHERE user_id= 1 AND status = 'approved' GROUP BY user_id, category
) t1 ON c.cat_no = t1.category
) d ON b.store_id = d.store_id AND b.max_distance >= d.total_distance
Use Correlated Subquery:
SELECT
dt.total_distance * dt.max_points
FROM (
SELECT SUM(t1.totald/c.cat_value) AS total_distance,
(
SELECT value_per_point
FROM points_martix
WHERE SUM(t1.totald/c.cat_value) >= max_distance
ORDER BY max_distance ASC LIMIT 1
) AS max_points
FROM mls_category AS c
JOIN (
SELECT SUM(distance) AS totald,
user_id,
category
FROM mls_entry
WHERE user_id= 1 AND
status = 'approved'
GROUP BY user_id, category
) AS t1 on c.cat_no = t1.category
) AS dt
Table 1 Table 2
_________________ ____________________
| ID| Name |Age | | ID| Cost | Date |
|---|-------|----| |---|-------|-------|
| 1 | Kirk | 33 | | 1 | 10 | 9/10 |
| 2 | Lonzo | 55 | | 1 | 20 | 7/8 |
| 3 | Dave | 44 | | 2 | 12 | 25/7 |
| 3 | 5 | 30/4 |
| 3 | 5 | 4/10 |
I want the result to be Kirk, who is 33, has a total cost of 30 and total dates to 2
etc.. (btw they enter their names and all this comes up)
The sql statement would be like this?
$sql= "SELECT Table1.Name, Table1.ID, Table2.ID, Table1.Age, SUM(Table2.Cost), SUM(Table2.Date)
AS count from Table1, Table2
WHERE Table1.ID = Table2.ID and Table1.Name = (my example here)"
$result = $conn->query($sql);
$Cost = 0;
$Date= 0;
$rec = $result->fetch_assoc();
$Date= $rec{'count'};
$Cost= $rec{'count'};
$Age = $rec{'Age'}
echo "$Name, who is $Age years old a total cost of $Cost and $Date total dates";
Im getting errors, saying my variables are undifined
so how would I put them into variables?
EDIT fixed
instead of using the sql to find it, i used result from a while loop that kept adding one to another variable (to count the date). The cost is able to do in both sql(sum) and result.
instead of using the sql to find it, i used result from a while loop that kept adding one to another variable (to count the date). The cost is able to do in both sql(sum) and result.
You were missing a group clause. I also put that in a subquery and used an INNER JOIN
SELECT Id, Name, Age, Cost, Dates
FROM Table1
INNER JOIN (
SELECT Id i, SUM(Cost) Cost,
COUNT(Date) Dates
from Table2
GROUP BY Id) t
ON i=Id
WHERE Name = 'Kirk'
You should also change one of the php statements to
$Cost= $rec{'Cost'};
Just use join..
SELECT table2.date ,SUM(cost) AS tatol FROM table1
JOIN table2 ON table2.id = table1.id
WHERE table1.id = 1
products_table: | p_id | name |
| 1 | name1 |
| 2 | name2 |
| 3 | name3 |
favourites_table: | id | p_id | deleted | group_id |
fetch-> | 1 | 1 | 0 | 11 |
| 2 | 1 | 0 | 11 |
fetch-> | 3 | 2 | 0 | 22 |
| 4 | 2 | 0 | 22 |
fetch-> | 5 | 3 | 0 | 33 |
| 6 | 3 | 0 | 33 |
$sth = $db->prepare(' SELECT a.p_id, b.name
FROM favourites_table AS a
INNER JOIN products_table AS b
ON a.p_id = b.p_id
WHERE a.deleted=0
GROUP BY a.group_id
ORDER BY a.id ASC
LIMIT 0, 10;');
$sth->execute();
while(($query_data = $sth->fetch()) !== false) {
echo $query_data['p_id'] . ':' . $query_data['name'] . '<br>';
}
This query fetches rows 1, 3, 5 from 'favourites_table'.
How to change it so it fetches "newest rows" (2, 4, 6) ?
Do I have to change the whole query or am I missing something?
You're confused by the pernicious misfeature in MySQL called the GROUP BY extension. Read this. http://dev.mysql.com/doc/refman/5.6/en/group-by-extensions.html
You want the rows you define as latest for each value of group_id. These rows are in fact the undeleted ones with the highest id values.
So, first you need to use a subquery -- a virtual table -- to find those rows, as follows:
SELECT MAX(id) AS id, group_id FROM favourites_table WHERE deleted = 0 GROUP BY group_id
Then, you need to use that resultset to find the right rows in your main query. You would do this like so:
SELECT a.p_id, b.name
FROM favourites_table AS a
INNER JOIN products_table AS b ON a.p_id = b.p_id
INNER JOIN (
SELECT MAX(id) AS id, group_id FROM favourites_table WHERE deleted = 0 GROUP BY group_id
) AS c ON a.id = c.id
GROUP BY a.group_id
ORDER BY a.id ASC
LIMIT 0, 10
This should get your results.
Question: Why order them oldest (lowest id value) first? Why only show the oldest ten results? Is that what you want?
I need a double SELECT sql query from 2 different tables with names visits & items
1.: SELECT visitid, visitdate, visitreason FROM visits WHERE personid = 10
2.: SELECT itemid, itemname, itemtime FROM items WHERE itemvisitid= visitid
I think I need to do a JOIN but don’t know exactly how.
Table examples:
Table: visits
visitid | personid | visitdate | visitreason
1 | 10 | 05/07/2014 | no reason
2 | 10 | 06/07/2014 | some reason
3 | 12 | 06/07/2014 | no reason
4 | 10 | 12/07/2014 | some other reason
Table: items
itemid | personid | itemvisitid | itemname | itemtime
1 | 10 | 2 | box | 23
2 | 10 | 2 | clock | 70
3 | 10 | null | water | 50
4 | 10 | null | paper | 40
5 | 12 | 3 | box | 26
What I have now is this:
$query = "SELECT visitid, visitdate, visitreason FROM visits WHERE personid = '10' ORDER BY visitdate DESC";
// 2nd select: "SELECT itemid, itemname, itemtime FROM items WHERE itemvisitid= visitid";
$db->setQuery($query);
$results = $db->query();
while($row = mysqli_fetch_array($results)){
echo "<tr>
<td>".$row['visitid'].", ".$row['visitdate']."</td>
<td>".$row['visitreason']."</td>
<td>".$row['itemid'].",".$row['itemname'].", ".$row['itemtime']."</td>
</tr>";
}
I need results to be something like this:
<tr>
<td>1, 05/07/2014</td><td>no reason</td><td></td>
<td>2, 06/07/2014</td><td>some reason</td><td>1, box, 23<br />2, clock, 70</td>
<td>4, 12/07/2014</td><td>some other reason</td><td></td>
</tr>
I guess your might to use GROUP_CONCAT like this:
DEMO: http://sqlfiddle.com/#!2/9d4e22/15
SELECT visitid, DATE_FORMAT(visitdate,'%m/%d/%Y'), visitreason,
GROUP_CONCAT(itemid,itemname, itemtime)
FROM visits left join items on visits.visitid = items.itemvisitid
WHERE visits.personid = 10
GROUP BY visitid, visitdate, visitreason
You might want to read this to know GROUP_CONCAT :
How to use GROUP_CONCAT in a CONCAT in MySQL
The document of GROUP_CONCAT() is here:
http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat
hope this helps.
SELECT `visits`.`visitid`, `visits`.`visitdate`, `visits`.`visitreason`,`items`.`itemname`, `items`.`itemtime` from `visits` INNER JOIN `items` ON `visits`.`personid`=`items`.`personid` WHERE `visits`.`personid` = '10' ORDER BY `visits`.`visitdate` DESC
if there is any error please change the field name personid in 'items' table.and then check.
This query:
SELECT v.visitid,
v.visitdate,
v.visitreason,
i.itemid,
i.itemname,
i.itemtime
FROM visits v
INNER JOIN items i
ON ( v.visitid = i.itemvisitid )
WHERE v.person_id = 10
ORDER BY v.visitdate DESC,
i.itemid ASC
will link both tables and produce a resultset that you can traverse using a double loop. The outer loop to process changes to the visit, and the inner to add every item visited in a particular visit.
I want sum values into my database by the same ID in the same table.
Table in database:
| ID | Value_o | Value_t | Value_tt |
| 1 | 40 | 20 | 10 |
query:
SELECT SUM(Value_o) AS Value_o, SUM(Value_t) AS Value_t, SUM(Value_tt) AS Value_TT
WHERE ID IN(1, 1)
And now the output id:
| Value_o | Value_t | Value_tt |
| 40 | 20 | 10 |
but I want:
| Value_o | Value_t | Value_tt |
| 80 | 40 | 20 |
I want get this output without JOIN.
Thanks!
PS. Sorry for my bad eng :/
Maybe this is what you are looking for:
SELECT
SUM(Value_o) AS Value_o,
SUM(Value_t) AS Value_t,
SUM(Value_tt) AS Value_TT
FROM
(
SELECT ID, Value_o, Value_t, Value_tt FROM Table1
UNION ALL
SELECT ID, Value_o, Value_t, Value_tt FROM Table1
) Table2
WHERE ID IN(1, 1);
Demo
The MySQL in operator doesn't work this way. Even if you have a value multiple times in the set, it doesn't duplicate the rows of your result.
If you want to have all the rows multiple times, you must use union all and sum over that
SELECT SUM(Value_o) AS Value_o, SUM(Value_t) AS Value_t, SUM(Value_tt) AS Value_TT
from (select * from mytable union all select * from mytable) t
WHERE ID IN (1)
Try this:
SELECT SUM(Value_o) AS Value_o, SUM(Value_t) AS Value_t, SUM(Value_tt) AS Value_TT
FROM TABLE
GROUP BY ID
HAVING ID = 1