Mysql GROUP BY or DISTINCT query usage in PHP - php

I'm a little bit confused about these kind of new query types for me (DISTINCT,GROUP BY etc.)
I have three tables in my database.
BRANDS
PRODUCTS
RECIPES
What I would like to do is to list BRANDS then look for PRODUCTS of that brand and look if there is a RECIPE of those products, then I want it to be written.
I'm able to write it with the basic queries;
$sql = "SELECT * FROM BRANDS";
$sql2 = "SELECT * FROM PRODUCTS WHERE BRANDID = 1";
$sql3 = "SELECT * FROM RECIPES WHERE PRODUCTID = 2";
but it repeats the brands.As far as I googled I have to use GROUP BY or DISTINCT in my query.
How should I create my query layout and which of them I should use?
Thank you.

I don't think you necessarily need to do all the distinct and grouping, unless your database has duplicate rows. You can select all of that in one query like so:
Select Brands.BrandId, Brands.BrandName, Products.ProductId, Products.ProductName, Recipes.*
From Brands
Inner Join Products On Products.BrandId = Brands.BrandId
Inner Join Recipes On Recipes.ProductId = Products.ProductId
Where
Brands.BrandId = 1 And
Products.ProductId = 2
Order By Brands.BrandId, Products.ProductId, Recipes.RecipeId
Please note that I assumed you have a Brands.BrandName and Products.ProductName column. This query will get you a complete recordset, filtered based on Brand and Product.

Related

how to join 2 tables in SQL

I need to join my variants table to my products table so that I am able to get the product_id from both tables, how can I put this into my existing query..?
I've tried to add it not working.
$query = query("
SELECT *
FROM products
FULL OUTER
JOIN variants WHERE product_id=" . escape_string($_GET['add']). " ");
It sounds like you are looking for an inner join, not a full outer join. You'll also want to specify the column you are joining both tables on:
$query = query("
SELECT *
FROM products
JOIN variants ON variants.product_id = products.product_id
WHERE products.product_id =" . escape_string($_GET['add']). " ");
*Note: I'm assuming product_id is a column on both the variants and products table. If, for example, the product_id of products is just id, you'll want to change the join condition to:
ON variants.product_id = products.id

PHP/SQL - querying relational DB for IDs but being able to query those IDs in seperate DB using ORDER BY

I have an ecommerce site where I have some products that can be in multiple categories.
I therefore have a products table, a categories table, and a product_categories table.
So what I do is query the product_categories table for the category ID of the category I want and get an array of product IDs like so:
$product_ids = [];
$params = [$category_id];
$sql = "SELECT * FROM product_categories WHERE category_id=?";
$stmt = DB::run($sql,$params);
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){
$product_id = $row['product_id'];
array_push($product_ids,$product_id);
}
I then have a show_products function which takes the array and spits out all of the products. However, this function has a foreach statement like so:
foreach($ids as $id){
$params = [$id];
$sql = "SELECT * FROM products WHERE id=?";
$stmt = DB::run($sql,$params);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
//show products
}
}
This is fine and works but I want to be able to determine the order of which the products are displayed, so in my products table I have an 'order_by' column and would like to do something like SELECT * FROM products WHERE id=? ORDER BY order_by ASC.
Obviously the way I'm set up at the moment means that it is doing the query for 1 id at a time so it can't order them in this way.
I was thinking to get around this I would need to query myproducts like I've done above but instead of showing the products at this stage I would get the order_by column and create another array and sort them by this order nand then actually use that array to query again and show the products.
Is there a better way of doing this?
**Note: I would like to keep my show_products function seperate for use in other parts of my site as it is fairly complicated (gets 'as low as' price and stock levels etc). So I want to be able to just pass an array of IDs to this function.
All you need is to move some logic to the SQL query from PHP code.
I think that for doing this you should modify your show_products function too, look at JOIN Syntax and GROUP_CONCAT function syntax.
Here is an example of what you can do with a simple JOIN and a GROUP_CONCAT aggregate function (assuming to have products.name and categories.description columns):
SELECT P.ID, P.name, GROUP_CONCAT(C.description)
FROM products P
INNER JOIN product_categories PC ON P.category_id = PC.id
INNER JOIN categories C ON PC.category_id = C.id
GROUP BY P.ID, P.name
This is my final SQL query.
SELECT product_categories.product_id
FROM product_categories INNER JOIN products ON product_categories.product_id=products.id
WHERE product_categories.category_id=?
ORDER BY products.order_by ASC

Select where class from wordpress database:

I need help to this select where class from wordpress database:
What I would like to achieve is to display the first 6 newcomer posts/records.
The path to the image, image name, property title, property features (How many Bedrooms and Bathroom etc. there is)
property price and property price unit (if it $ or Danish kroner etc.)
At this link All properties here you can see what i will like to achieve on my front page, just without google map and the sort list and only the 6 first post:
All properties
This are tables: wp_wpl_properties, wp_wpl_units, wp_wpl_items to achieve my goal so i tried to make this select query:
enter code here
<?php
global $wpdb;
$results = $wpdb->get_results
("SELECT * FROM wp_wpl_properties,wp_wpl_units,wp_wpl_items
where wp_wpl_properties.price_unit= wp_wpl_units.id and wp_wpl_properties.id= wp_wpl_items.parent_id LIMIT 6;");
foreach ( $results as $result ) {
?>
I have attached table files to this question, here:
wp_wpl_units.pdf
wp_wpl_items.pdf
wp_wpl_properties (1).sql
The code I've made does not make any errors.
My problem is that i get the same record displayed 3 times at the fist columns and the same at the next 3 column, hope this make sens :)
Here is a link to my frontpage: My frontpage
Do you want like this?
$results = $wpdb->get_results ("
SELECT * FROM wp_wpl_properties
join wp_wpl_units on wp_wpl_properties.living_area_unit= wp_wpl_units.id
join wp_wpl_properties on wp_wpl_properties.id= wp_wpl_items.parent_id LIMIT 6");
or
$results = $wpdb->get_results ("
SELECT * FROM wp_wpl_properties
join wp_wpl_units on wp_wpl_properties.living_area_unit= wp_wpl_units.id
join wp_wpl_properties on wp_wpl_properties.id= wp_wpl_items.parent_id
where wp_wpl_properties.id= 1");
$results = $wpdb->get_results
("SELECT * FROM wp_wpl_properties
Inner Join wp_wpl_units ON wp_wpl_properties.living_area_unit = wp_wpl_units.id
Inner Join wp_wpl_items ON wp_wpl_properties.id= wp_wpl_items.parent_id
LIMIT 6;");
In your MySQL query,
SELECT * FROM wp_wpl_properties,
wp_wpl_units,
wp_wpl_items
where wp_wpl_properties.price_unit=wp_wpl_units.id
and wp_wpl_properties.id= wp_wpl_items.parent_id
LIMIT 6
MySQL individually checks each of the three columns differently and generates output for all of them even though they are same.
Doing an inner join instead of checking individually on three columns would be the solution. Like,
SELECT DISTINCT * FROM wp_wpl_properties as props
Inner Join wp_wpl_items as items ON items.parent_id = props.id
Inner Join wp_wpl_units as units ON units.id = props.living_area_unit
LIMIT 6
And instead of select distinct * from, get only the columns you need. it will speed up the query to a large extent!
like SELECT DISTINCT props.ID, items.ID FROM ....
Hope this helps.

product search across 3 database tables

I am trying to create a product search feature on an E-commerce website I am building but am having a little trouble.
I have 3 tables (categories, sub_categories, products)
Categories table fields: (categoryID, categoryName, active, image)
sub_categories table fields: (categoryID, categoryName, parentCatID, active, image)
products table fields: (productID, shortDescription, longDescription, image, catID, subCatID, active, price, delivery, weight)
Im trying to get my search to find a product if a user types in any part of the short description or long description or if the user types in any part of the category or sub category names it should find all products within those categories.
I dont know whether to do a JOIN or multiple SQL queries. to be honest i've been tinkering with it for a few hours but havnt really gotten anywhere and am now back at the drawing board asking for help
my first attempt looked like this:
$catSelect = mysqli_query($con,"SELECT * FROM categories WHERE categoryName LIKE '%{$term}%'");
$row1 = mysqli_fetch_row($catSelect);
$subCatSelect = mysqli_query($con,"SELECT * FROM sub_categories WHERE categoryName LIKE '%{$term}%' OR parentCatID = '%{$row1[0]}%'");
$row2 = mysqli_fetch_row($subcatSelect);
$productSelect = mysqli_query($con,"SELECT * FROM products WHERE short_description LIKE '%{$term}%' OR long_description LIKE '%{$term}%' OR subCatID = '%{$row2[0]}%' OR catID = '%{$row1[0]}%'");
my final attempt looks like this
mysqli_query($con,"SELECT * FROM products INNER JOIN categories ON products.catID = categories.categoryID WHERE categories.categoryName LIKE '%{$term}%'") or die(mysqli_error());
Could someone help me with the SQL query I need to use?
Try this:
SELECT
p.productID
FROM
products p
LEFT JOIN categories c
ON c.categoryID = p.catID
LEFT JOIN sub_categories sc
ON sc.categoryID = p.subCatID
WHERE
p.shortDescription LIKE '%keyword%'
OR p.longDescription LIKE '%keyword%'
OR c.categoryName LIKE '%keyword%'
OR sc.categoryName LIKE '%keyword%'
You need to do a join, on all three tables, with a where clause that queries the fields you want to search. Something like this:
select * from
products
inner join categories on products.catID = categories.categoryID
inner join sub_categories on products.subCatID = sub_categories.categoryID
where
products.shortDescription like '%query%'
or products.longDescription like '%query%'
or categories.categoryName like '%query%'
or sub_categories.categoryName like '%query%'
;
where the query is the search query string.
this can be helpful to you.....
SELECT * FROM products AS PT
LEFT JOIN Categories AS CT ON CT.catID = PT.catID
LEFT JOIN sub_categories AS SCT ON SCT.subCatID = PT.subCatID
WHERE
PT.active = 'YES' AND
(PT.shortDescription LIKE '%shortDescription%' OR
PT.longDescription LIKE '%longDescription%' OR
CT.category LIKE '%category%' OR
SCT.categoryID LIKE '%sub category%' )
you just put your values using php varrible you can get your search results.
Why don't you use lucene-solr for this?

mysql join getting a value or a null into a column

I am very new to SQL, so I am having a couple problems figuring things out. The database is for an online store, and the structure is something like this:
users: UserID, UserName, etc.
pricelists: PricelistID, UserID, ProductItemID, Price
productitems: ProductItemID, ProductID, ItemID
products: ProductID, ManufacturerID, WebPageText, etc.
Each product can have one or more items (e.g. if the product page is selling T-shirts, there may be 5 different T-shirt variations for sale). That's pretty normal. What's not normal is that the pricing for each item is determined by what's in the user's pricelist, because each user is assigned particular pricing. Not all users have a price assigned for every item.
Here is the question: The requirement from management is that the user should be able to see every product, even if that product is not in the user's pricelist. If the user has no pricelist entry for a productitem, the page should display, "Contact us for pricing." I have not been able to figure out how to do this with one query. Every join that I attempted involving the pricelist table threw out products for which the user didn't have a price assigned. I am given only the ProductID and UserID. I have put my code below, which is a mix of mysql and PHP. It works, but it is clunky, especially seeing as I have to redo the second query over and over. Please tell me how I really ought to be doing it.
$query_product = sprintf("SELECT * , (items.Stock - (SELECT Coalesce(Sum(DetailQuantity),0)
FROM orderdetails
INNER JOIN orders ON OrderID = DetailOrderID
INNER JOIN productitems ON orderdetails.ProductItemID = productitems.ProductItemID
INNER JOIN products ON productitems.ProductID = products.ProductID
INNER JOIN items ON productitems.ItemID = items.ItemID
WHERE OrderDate > ProductUpdateDate))*ProductLive
AS NumLeft
FROM productitems
INNER JOIN products ON products.ProductID = productitems.ProductID
JOIN items ON productitems.ItemID = items.ItemID
WHERE products.ProductID = %s",GetSQLValueString($ProductID, "int"));
$product = mysql_query($query_products, $x) or die(mysql_error());
$row_product = mysql_fetch_assoc($product);
//after narrowing down to one productitem, either through user selections or while looping through $row_product:
$query_price = sprintf("SELECT Price FROM pricelists
WHERE UserID = %s AND ProductItemID = %s", GetSQLValueString($UserID, "int"), GetSQLValueString($row_product['ProductItemID'], 'int'));
$price = mysql_query($query_price, $x) or die(mysql_error());
$row_price = mysql_fetch_assoc($price);
$row_product['Price'] = $row_price['Price'];
Later in the code, I check whether $row_products['Price'] is empty or not to determine what is displayed on the page.
EDIT: I thought this would be obvious, but ... I have to limit pricelists by WHERE UserID = %s. That means I can't just tack on a LEFT JOIN pricelists ON pricelists.ProductItemID = productitems.ProductItemID, which was actually the first thing I tried, and which does not work. Limiting the outer join in the WHERE statement turns it into an inner join.
Add the pricelists table as an LEFT join to your main query:
SELECT field1, field2, ..., pl.*
FROM orderdetails
INNER JOIN orders ON OrderID = DetailOrderID
...
LEFT JOIN pricelists pl PN pl.ProductItemID = productitems.ProductItemID
..
In your code check if the price in the pricelists table is null, if so, show the text.
You should look into using an outer join for this. Heres a great description of the difference between an inner and outer join -> inner join vs outer join

Categories