How to get father name in php - php

I have a sample code:
products(id, parent_id, name)
1 | 0 | product1
2 | 0 | product2
3 | 1 | product1_1
4 | 1 | product1_2
5 | 2 | product2_1
6 | 2 | product2_2
And query:
SELECT prod.id, prod.name
FROM `products` AS prod
INNER JOIN `products` AS prod_parent ON prod_parent.product_id = prod.parent_id
But result is:
3 | product1_1
4 | product1_2
5 | product2_1
6 | product2_2
How to get parent father
1 | product1
2 | product2

Be specific in your SELECT list which table you want them from. This will give you all four columns, but you can trim it to only those you need.
SELECT
prod.id AS prod_id,
prod.name AS prod_name,
prod.parent_id AS parent_id,
prod_parent.name AS parent_name
FROM `products` AS prod
LEFT JOIN `products` AS prod_parent ON prod_parent.product_id = prod.parent_id

Related

How to select unique value from many to many mysql relationship

Hi I got confused in this sql case. I am using mysql Ver 15.1 Distrib 10.2.31-MariaDB. And let's say I have 3 table products, categories, and product_categories as pivot table.
Here is the data example:
products:
| id | name |
------------------------
| 1 | asd wef |
| 2 | gggg2222 |
| 3 | pppga 99 |
| 4 | lalala 55 |
And for categories:
| id | level | parent_id | name |
-----------------------------------
| 20 | 1 | | Fashion |
| 22 | 2 | 20 | Top |
| 23 | 3 | 22 | T-Shirt |
| 24 | 3 | 22 | Jacket |
And for the pivot table, product_categories:
| product_id | category_id |
--------------------------------
| 1 | 20 |
| 1 | 22 |
| 1 | 23 |
| 2 | 22 |
| 2 | 20 |
| 3 | 20 |
| 4 | 20 |
So as you can see from pivot table only product_id = 3 & 4 that stop in category level 1. And product_id = 2 only stop in category level 2.
What I would like to achieve here is when I select from categories table. I can count how many product that stopping here. This is example of the data that I want to get.
"categories": [
{
"id": 20,
"total_product": 4
"stopped_product": 2
},
{
"id": 22,
"total_product": 3
"stopped_product": 1
}
]
So far I tried using group by:
SELECT * FROM product_categories WHERE product_id IN (1, 2, 3, 4) GROUP BY product_id HAVING category_id=20
output:
| product_id | category_id |
--------------------------------
| 1 | 20 |
| 3 | 20 |
| 4 | 20 |
Expected Output
| product_id | category_id |
--------------------------------
| 3 | 20 |
| 4 | 20 |
You can use a CTE to generate a list of stop categories for each product and then JOIN that to the categories and product_categories tables to count the total number of products and number of stopped products for each category:
WITH prods AS (
SELECT product_id, MAX(category_id) AS stop_cat
FROM product_categories
GROUP BY product_id
)
SELECT c.id AS category_id,
COUNT(DISTINCT pc.product_id) AS total_product,
SUM(c.id = p.stop_cat) AS stopped_product
FROM categories c
JOIN product_categories pc ON pc.category_id = c.id
JOIN prods p ON p.product_id = pc.product_id
GROUP BY c.id
Output (for your sample data)
category_id total_product stopped_product
20 4 2
22 2 1
23 1 1
Demo on dbfiddle
I guess you want max values only
SELECT product_id,MAX(category_id) as category_id FROM product_categories WHERE product_id IN (1, 2,
3, 4)
GROUP BY product_id
HAVING category_id=20
Here is you can find category-wise product count and ids:
SELECT c.name as categoryName, c.level, COUNT(pc.product_id) as productCount, GROUP_CONCAT(pc.product_id) as productIds
FROM product_categories pc JOIN categories c ON c.id = pc.category_id
WHERE 1
GROUP by c.id

Stuck in building MySQL query

Given an example of table:
id | item_id | user_id | bid_price
----------------------------------
The task is to select rows with minimum bid_price for each item_id in the provided set.
For example: item_id = [1, 2, 3] - so I need to select up to three (3) rows, having a minimum bid_price.
Example of data:
id | item_id | user_id | bid_price
----------------------------------
1 | 1 | 11 | 1
2 | 1 | 12 | 2
3 | 1 | 13 | 3
4 | 1 | 14 | 1
5 | 1 | 15 | 4
6 | 2 | 16 | 2
7 | 2 | 17 | 1
8 | 3 | 18 | 2
9 | 3 | 19 | 3
10 | 3 | 18 | 2
Expected result:
id | item_id | user_id | bid_price
----------------------------------
1 | 1 | 11 | 1
7 | 2 | 17 | 1
8 | 3 | 18 | 2
Actually, I'm using Symfony/Docine DQL, but it will be enough with a plain SQL example.
For the all the columns in the rows you could use a inner join on subselect for min bid price
select m.id, m.item_id, m.user_id, m.bid_price
from my_table m
inner join (
select item_id, min(id) min_id, min(bid_price) min_price
from my_table
where item_id IN (1,2,3)
group by item_id
) t on t.item_id = m.item_id
and t.min_price= m.bid_price
and t.min_id = m.id
or .. if you have some float data type you could use a acst for unsigned
select m.id, m.item_id, m.user_id, cast(m.bid_price as UNSIGNED)
from my_table m
inner join (
select item_id, min(id) min_id, min(bid_price) min_price
from my_table
where item_id IN (1,2,3)
group by item_id
) t on t.item_id = m.item_id
and t.min_price= m.bid_price
and t.min_id = m.id
You can use MIN() with GROUP BY in the query:
SELECT id, item_id, MIN(bid_price) AS min_bid, user_id
FROM your_tbl
GROUP BY item_id
HAVING item_id in(1, 2, 3);
Use this query:
SELECT id, item_id, user_id, min(bid_price) as bid_price
FROM YOUR_TABLE_NAME
GROUP BY item_id;

Sort product data from multiple tables in MySQL

I have two tables. The first:
Products table:
+----+-----------+
| id | name |
+----+-----------+
| 1 | Product 1 |
| 2 | Product 2 |
| 3 | Product 3 |
+----+-----------+
This contains product names and other table contains prices for different product variants:
Products prices table:
+-----+------------+-------------+
| id | product_id | price |
+-----+------------+-------------+
| 5 | 1 | 12.00 |
| 6 | 1 | 32.00 |
| 11 | 1 | 56.00 |
| 14 | 2 | 11 |
| 44 | 3 | 12 |
+-----+------------+-------------+
I need to create a sort on price (lowest and highest)
Yes you can, for this you have to use JOIN and ORDER BY clause.
Ex:
select t1.id, t2.product_id t2.price FROM table1 t1 JOIN table2 t2 ON t1.id = t2.pid ORDER BY t2.price
Mysql join with order by reference guide
You can try this code...
SELECT product_tbl.name, product_tbl.id, product_price.product_id, product_price.price FROM product_tbl, product_price WHERE product_tbl.id=product_price.product_id ORDER BY product_price.price DESC;
Sample Query:
select t1.[id],t1.[name],t2.[price]
from [yourtable1] t1
Join [yourtable2] t2 on
t1.[id]=t2.[product_id]
Order by t2.[price] Asc;

Mysql limit the number of returned results based on the unique values from a single column

I have three tables,
Product_to_categories => contains two columns (Category_id, Product_id)
Product => contains a few columns (product_id, name, sku, ...)
categories => contains a few columns (category_id, name, ....)
I would like to get a result set for the first 10 unique category_id's joined with the product table, a category can have many product assigned to it, i want all products within one category returned, but i'd like to only get the products from the first 8 categories...
Current query:
SELECT p2c.category_id, p.pname, c.category_name
FROM product p LEFT JOIN product_to_category p2c
ON (p.product_id = p2c.product_id)
Left Join category c (p2c.category_id = c.category) LIMIT 0,8
Current output
catID | p.name | catName |<br/>
1 | docs | shoe<br/>
1 | bob | shoe<br/>
1 | mom | shoe<br/>
1 | cat | shoe<br/>
1 | dang | shoe<br/>
1 | kit | shoe<br/>
2 | pis | book<br/>
2 | jiz | book<br/>
Currently i only get the first 8 results regardsless, however i am looking to get the following output:
catID | p.name | catName |<br/>
1 | docs | shoe<br/>
1 | bob | shoe<br/>
1 | mom | shoe<br/>
1 | cat | shoe<br/>
1 | dang | shoe<br/>
1 | kit | shoe<br/>
2 | pis | book<br/>
2 | jiz | book<br/>
3 | docs | shirt<br/>
3 | bob | shirt<br/>
3 | mom | shirt<br/>
4 | cat | light<br/>
4 | dang | light<br/>
5 | kit | sound<br/>
6 | pis | mic<br/>
6 | jiz | mic<br/>
7 | docs | pen<br/>
7 | bob | pen<br/>
7 | mom | pen<br/>
7 | cat | pen<br/>
8 | dang | lace<br/>
8 | kit | lace<br/>
8 | pis | lace<br/>
8 | jiz | lace<br/>
i would like the resultset to contain results of all products that are assigned to the first 8 categories...
Please advise.
Thanks
Hadi
I'm a bit unsure why your query is starting from the product table, so I'm not going to - but aside from this, I think what you need is:
SELECT c.category_id, p.pname, c.category_name
FROM category c
INNER JOIN product_to_category pc ON c.category_id = pc.category_id
INNER JOIN product p ON pc.product_id = p.product_id
WHERE c.category_id in (SELECT TOP 8 category_id FROM Category)
ORDER BY 1, 2

Parent / Child in same table

I have table structure like below:
id |parent|name |value
1 | 0 | aaa |
2 | 0 | bbb |
3 | 0 | ccc |
4 | 1 | | 111
5 | 1 | | 222
6 | 3 | | 333
I want to display parent if it has child records.
Like:
(parent id + name + value first child)
1 - aaa - 111
3 - ccc - 333
There is no meaning of the first child in the database, you can get the first child by the mininum of the id or the minimum of the value, but the values are not stored with a specific order in the table, so you can't tell which value is the first one.
But, assuming that the id is auto incremental column, then value of the first child is the value of the minimum id, then you can do this:
SELECT
t1.parent,
t2.name,
t1.value
FROM tablename AS t1
INNER JOIN
(
SELECT MIN(id) AS id, parent
FROM tablename
GROUP BY parent
) AS t22 ON t22.id = t1.id AND t1.parent = t22.parent
INNER JOIN tablename AS t2 ON t1.parent = t2.id;
See it in action here:
SQL Fiddle Demo
This will give you :
| PARENT | NAME | VALUE |
-------------------------
| 1 | aaa | 111 |
| 3 | ccc | 333 |
Or: You can get it by the minimum value:
SELECT
t1.parent,
t2.name,
MIN(t1.value) AS value
FROM tablename AS t1
INNER JOIN tablename AS t2 ON t1.parent = t2.id
GROUP BY t1.parent, t2.name;
See it in action:
SQL Fiddle Demo
This will give you:
| PARENT | NAME | VALUE |
-------------------------
| 1 | aaa | 111 |
| 3 | ccc | 333 |

Categories