How to count if value of a variable is repeated? - php

I am learning how to work with MySQL, and at the moment I succeed to show data from my table, using:
while($objResult2 = mysqli_fetch_assoc($objQuery_product)) {
Results are shown by using this variable $objResult2["id_product"]; this way i can take from DB any field I want like: $objResult2["name"]; $objResult2["email"]; etc.
But what i do if i have in the table more rows with the same id_product?
I want to write a if statment, which counts if id_product repeats. How to do that? If it is a lot of work, atleast please give me an idea of the right tutorial that I must read. Because i am trying second day to fix this, and searched google but i didnt find what i need, or maybe i coulndt understand it....
This is my query
$sql_product = "SELECT * FROM ps_product AS prod";
$join_product = " LEFT JOIN ps_product_lang AS lang ON lang.id_product = prod.id_product";
$join2_product = " LEFT JOIN ps_stock_available AS stok ON stok.id_product = prod.id_product";
$where_product =" WHERE prod.id_category_default = $idp AND lang.id_lang = 8";
$sql_product = $sql_product.$join_product.$join2_product.$where_product;
$objQuery_product = mysqli_query($objConnect, $sql_product) or die ("Error Query [".$sql_product."]");

You can simple remove the same id_product using DISTINCT keyword in your query. Such as:
SELECT DISTINCT id_product FROM my_table
This will give you results with different ids only.
The second way of doing it is taking the output values inside an array.
In your while loop:
$my_array[] = $objResult2["id_product"];
Then using array_filter remove all the duplicates inside the array.
YOu can also use array_count_values() if you want to count the duplicate values.

Ok here we go. For example you are fetching data with this query.
select id_product, name from PRODUCTS;
Suppose above query gives you 5 records.
id_product name
1 bat
2 hockey
2 hockey
3 shoes
4 gloves
Now you got 2,2 and hockey, hockey. Instead of thinking this way that you have to introduce an if statement to filter repeating records or same name or id_product records.
Rewrite your sql query like this.
select distinct id_product, name from PRODUCTS;
Or if you need count of each then my friend you will write your query something like this...
Graham Ritchie, if Andrei needs count of each repeating record then we will do something like this in our query.
SELECT PRODUCT_ID,
COUNT(PRODUCT_ID) AS Num_Of_Occurrences
FROM PRODUCTS
GROUP BY PRODUCT_ID
HAVING ( COUNT(PRODUCT_ID) > 1 );

SELECT id_product,COUNT(*) AS count
FROM tablename
GROUP BY id_product;
This query will then return you two items in your query
$objResult2["id_product"] //and
$objResult2["count"]
The if statement is then just
if($objResult2["count"] > 1){
//Do whatever you want to do with items with more than 1 occurence.
//for this example we will echo out all of the `product_id` that occur more than once.
echo $objResult2["id_product"] . " occurs more than once in the database<br/>";
}

Related

Get two types of number of rows with minimum lines

I have the following query.
$sql = "SELECT customer FROM furniture WHERE id = :id AND category = :cat";
$stmt = $connectdb->prepare($sql);
$stmt->execute(array(':id'=>$id, ':cat'=>"1"));
$resulta = $stmt->fetchAll(PDO::FETCH_ASSOC);
$rowcount = count($result);
This works perfectly. But I have a requirement to get the number of rows from WHERE id = :id AND category = :cat as well as to get the number of rows from WHERE category = :cat. Is it possible to do both of them without having to write all those SELECT query lines twice?
You can use conditional sum to get the 2 different counts something as
select
sum(id = :id AND category = :cat) as count1,
sum(category = :cat) as count2
from furniture;
Later you just fetch the records and get the values of count1 and count2
NOTE : If you just do row count it will always return 1 since its using the aggregate function
I would suggest that you write the query as:
select sum(id = :id) as numCatId, count(*) as numCat
from furniture
where cat = :cat;
Putting the condition in the where clause allows MySQL to use an index on furniture(cat) (or better yet furniture(cat, id). In general, it is a good idea to put common filtering conditions in the where clause. This reduces the number of rows needed for processing the rest of the query.

PHP 'IN' query returns only 1 row

Can anyone explain me why the last query returns always 1 row. it should return more than 1 because there're a lot of records in the database!
Sorry for my bad english
$query=mysql_query("SELECT book_id FROM ".DB_PREF."books_cats_list WHERE cat_id='".$cat."'");
if($row=mysql_num_rows($query))
{
//fetching all books from $cat category
for($i=0; $fetch=mysql_fetch_assoc($query); $i++)
{
$records[$i]=$fetch['book_id'];
}
//Joining all records in a string for next query
$records=implode(",",$records);
//returning num rows if there're book_id records in $records array
$query=mysql_query("SELECT * FROM ".DB_PREF."books WHERE book_id IN ('".$records."')");
$rows=mysql_num_rows($query);
echo $rows;
Your query is going to look like this:
SELECT * FROM books WHERE book_id IN ('2,3,4,5')
Note how inside the IN, it's all one string. This one string will be converted to an int. This happens by stopping at the 1st non-number character. So, the query becomes:
SELECT * FROM books WHERE book_id IN (2)
Try to remove the single quotes inside the IN.
NOTE: If your values aren't ints, try changing the the implode to: implode("','",$records), and keep the quotes inside the IN.
At a quick glance I suggest the for loop:
for($i=0; $fetch=mysql_fetch_assoc($query); $i++)
Should be a while loop:
while($fetch=mysql_fetch_assoc($query))
I expect it is only doing one record with that for loop code.
I suggest however you do a left join select
SELECT * FROM books_cats_list as cat
left join books as book on cat.book_id = book.book_id
WHERE cat.cat_id='$cat'
This will be far more optimal in terms of database performance I expect.

How to add a single column php/mysql

I'm trying to add a single column in a db query result. I've read about the SUM(col_name) as TOTAL, GROUP BY (col_name2).
But is there a way i can only SUM the column without any GROUPing? I a case whereby all col_name2 are all unique.
For example... I have a result with the following col headers:
course_code
course_title
course_unit
score
grade
Assuming this have 12 rows returned into an HTML table. Now i want to perform SUM() on all the values (12 rows) for the column course_unit, in other to implement a GPA school grading system.
How can i achieve this.
Thanks.
SELECT SUM(col_name) as 'total' FROM <table>
GROUP BY is required only if you want to sum subsets of the rows in the table.
You can find sum or any aggregate db functions (such as count, avg, etc) for most cases without using group clause. Your sql query may look something like this:
SELECT SUM(course_unit) as "Total" FROM <table_name>;
As comments below have already pointed out: SELECT SUM(course_unit) AS total FROM your_table;. Note that this is a separate query to the one with which you retrieve the table data.
This does it in php. I'm not sure how to do it with pure sql
$query = "SELECT * FROM table";
$result = mysql_query($query);
$sum = 0;
while($row = mysql_fetch_assoc($result))
{
$sum+= intval($row['course_unit']);
}
echo $sum;
SELECT
course_code,
course_title,
course_unit,
score, grade,
(select sum(course_unit) from TableA) total
from TableA;

SELECT a few rows out of MYSQL

I need to select category ids from my sql database.
I have a variable $product_id and for each product id there are three rows in a table that i need to select using PHP.
If I do "SELECT * FROM table_name WHERE product_id='$prodid'"; I only get the one on the top.
How can I select all three category_ids which contain the same product_id?
I suppose you are using PHP's mysql functions, is this correct? I am figuring that your query is actually returning all three rows but you aren't fetching all of them.
$sql = "SELECT * FROM table_name WHERE product_id='$prodid'";
$r = mysql_query($sql, $conn); //where $conn is your connection
$x = mysql_fetch_SOMETHING($r); //where something is array, assoc, object, etc.
The fetch function gives only one row at a time. You say you need three so it needs to be executed three times.
$x[0] = mysql_fetch_assoc($r);
$x[1] = mysql_fetch_assoc($r);
$x[2] = mysql_fetch_assoc($r);
OR this would be better
while($curRow = mysql_fetch_assoc($r)) //this returns false when its out of rows, returns false
{
$categoryIds[] = $curRow['category_id'];
}
If this doesn't do it then your query is actually returning only one row and we need to see your tables/fields and maybe sample data.
SQL seems to be correct, but Why do you store product_id in categories table? if it's one-to-many relation it would be better to store only category_id in products table.
The SQL query is correct for what you want to do. It will select all the records in table_name with the field product_id = $prodid (not only 1 or 3 but any that matches the variable)
To select a few records you should use the LIMIT keyword
You should look inside your table structure and the variable $prodid to find problems.

Looping through data from multiple tables PHP/Mysql

HI all,
I am trying to figure out how to put this into words even, but I am wanting to know how to format the output from each table separately in a "multiple table" mysql query. The output from the table1 "wall" is formatted within a while loop, but the content from table2 "actions" is already formatted(as 1 line of text with links) before it is inserted into the table(column action_body), so inside the loop I would only be outputting the action_date and action_body columns from the actions table.
I am probably not using the correct sql method(if Im doing anything right at all, that is) for the results I need, so feel free to correct my novice example, or suggest a new way to approach this.
Query:
$query = "SELECT wall.wall_id, wall.wall_owner_id, wall.wall_user_id,
wall.wall_post_date, wall.wall_post_content, actions.action_id,
actions.action_date, actions.action_user_id, actions.action_title,
actions.action_body FROM wall, actions
ORDER BY wall.wall_post_date, actions.action_date DESC";
$result = mysql_query($query);
while( $rows = mysql_fetch_assoc($result) {
// What to put here
}
Any help is appreciated, thanks, Lea
Update after comments
SELECT w.* FROM (
(SELECT
'w' as type,
wall_id as id,
wall_owner_id as owner_id,
wall_user_id as user_id,
wall_post_date as post_date,
NULL as title,
wall_post_content as content
FROM wall
WHERE wall_owner_id = x # user id of owner
)
UNION
(SELECT
'a' as type,
action_id as id,
action_user_id as owner_id,
NULL as user_id,
action_post_date as post_date,
action_title as title,
action_body as content
FROM actions
WHERE action_user_id = x # user id of owner
)
) w
ORDER BY w.post_date DESC
Because you don't JOIN on a specific field, you're gonna get every row-row combination of the two tables, which is a whole lot more data than you probably want.
You'd be better of by doing 2 queries, one for each table. While looping through the result of each table, you can collect the data you want in one array, with the field you want to sort it by as array key.
Then you sort the array, and loop through it to print it out.

Categories