How can I create this mysql "SELECT" query? - php

I have two mysql tables named 'categories' and 'products'.
These are data of that tables.
mysql> select * from categories;
+-------------+--------+----------------------+-------------+
| category_id | parent | name | description |
+-------------+--------+----------------------+-------------+
| 1 | NULL | Products | NULL |
| 2 | 1 | Computers | NULL |
| 3 | 2 | Laptops | NULL |
| 4 | 2 | Desktop Computers | NULL |
| 5 | 2 | Tab PCs | NULL |
| 6 | 2 | CRT Monitors | NULL |
| 7 | 2 | LCD Monitors | NULL |
| 8 | 2 | LED Monitors | NULL |
| 9 | 1 | Mobile Phones | NULL |
| 10 | 9 | LG Phone | NULL |
| 11 | 9 | Anroid Phone | NULL |
| 12 | 9 | Windows Mobile | NULL |
| 13 | 9 | iPad | NULL |
| 14 | 9 | Samsung Galaxy | NULL |
| 15 | 1 | Digital Cameras | NULL |
| 16 | 1 | Printers and Toners | NULL |
| 22 | 1 | Computer Accessaries | NULL |
| 23 | 22 | USB Cables | NULL |
| 24 | 22 | Network Cables | NULL |
+-------------+--------+----------------------+-------------+
24 rows in set (0.00 sec)
mysql> select product_id, category_id from products;
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1 | 24 |
| 2 | 6 |
| 3 | 6 |
| 4 | 6 |
+------------+-------------+
4 rows in set (0.05 sec)
Now I need to create a select query to get products to each category. I have already have category_id.
This is how I tried it:
SELECT * FROM products
WHERE category_id = 6
ORDER BY added_date DESC
My question is when I creating this select query I need all the products if one category have its subcategories. That mean, if category_id is 2, then I need to get all the products including its sub categories.
Can anybody tell me how I create this select query?
Thank you.

SELECT *
FROM products
WHERE category_id = 2 OR
category_id IN (SELECT category_id
FROM categories
WHERE parent = 2)
ORDER BY added_date DESC

try this.
select a.*,b.* from categories a inner join products b on a.category_id = b.category_id where a.category_id='$Category_id' or a.parent_id='$category_id'

You can do it using a sub-query to get category_id values whose parent is 2:
SELECT *
FROM products
WHERE category_id = 2 OR
category_id IN (SELECT category_id
FROM categories
WHERE parent = 2)
ORDER BY added_date DESC

All of the above answers will work but only for one level deep of categories. If you need sub-sub-categories then I'd suggest using something called MPTT. This will require 2 new fields in your categories database table though (typically called left and right).

Related

MYSQL OR SQL SELECT with both COMPARE (HAVING) and GROUP

I have three tables in a database and want to sum and compare in one SELECT statement.
The logic is that if one article runs low in stock it should be selected. An article runs low if the summarized quantity of all rows with the same artID in the table Articles in stock (an article can have several rows in the table and therefore needs to be summarized) is lower or equal to the column warning in the row with the corresponding ID. This is also warehouse specific, meaning that an article can be fully stocked in one warehouse, and at the same time running low in another. Which is why it is needed to summarize grouped on a specific warehouse.
Information about which warehouse is running low, and such as artNr for the article is also needed, which can be found in table Articles
Articles
+----+-------+---------+
| ID | artNr | warning |
+----+-------+---------+
| 1 | LA08 | 5 |
| 2 | LA09 | 10 |
| 3 | LA58 | 0 |
+----+-------+---------+
warehouse
+----+-------+
| ID | artID |
+----+-------+
| 3 | 1 |
| 4 | 1 |
| 5 | 2 |
+----+-------+
Articles in stock
+----+-------+-------------+----------+
| ID | artID | warehouseID | quantity |
+----+-------+-------------+----------+
| 1 | 1 | 3 | 10 |
| 2 | 1 | 5 | 15 |
| 3 | 2 | 5 | 45 |
| 4 | 1 | 3 | 20 |
| 5 | 3 | 5 | 4 |
+----+-------+-------------+----------+
select a.id, s.warehouseID, sum(s.quantity)
from articles a
join articles_in_stock s on a.id = s.artID
group by a.id, s.warehouseID
having sum(s.quantity) <= a.warning

Find the ranking for Concatenated rows in mysql

I have a table with concatenated values within both rows, I am therefore uniquely retrieve ranking for each row in the tables.
UPDATE
The other tables has been added to question
NamesTable
NID | Name |
1 | Mu |
2 | Ni |
3 | ices |
GroupTable
GID | GName |
1 | GroupA |
2 | GroupB |
3 | GroupC |
MainTable
| NID | Ages | Group |
| 1 | 84 | 1 |
| 2 | 64 | 1 |
| 3 | 78 | 1 |
| 1 | 63 | 2 |
| 2 | 25 | 2 |
| 3 | 87 | 2 |
| 1 | 43 | 3 |
| 2 | 62 | 3 |
| 3 | 37 | 3 |
Now the first Name is equated to the first age in the table, I am able to equate them using php and foreach statements, Now the problem is with the ranking of the ages per each group. I am ranking the names uniquely on each row or group.
Results which is expected
| Names | Ages | Group | Ranking |
| Mu,Ni,ices | 84,64,78 | 1 | 1,3,2 |
| Mu,Ni,ices | 63,25,87 | 2 | 2,3,1 |
| Mu,Ni,ices | 43,62,37 | 3 | 2,1,3 |
In my quest to solving this, I am using GROUP_CONCAT, and I have been able to come to this level in the below query
SELECT
GROUP_CONCAT(Names) NAMES,
GROUP_CONCAT(Ages) AGES,
GROUP_CONCAT(Group) GROUPS,
GROUP_CONCAT( FIND_IN_SET(Ages, (
SELECT
GROUP_CONCAT( Age ORDER BY Age DESC)
FROM (
SELECT
GROUP_CONCAT(Ages ORDER BY Ages DESC ) Age
FROM
`MainTable` s
GROUP by `Group`
) s
)
)) rank
FROM
`MainTable` c
GROUP by `Group`
This actually gives me the below results.
| Names | Ages | Group | Ranking |
| 1,2,3 | 84,64,78 | 1 | 7,9,8 |
| 1,2,3 | 63,25,87 | 2 | 5,6,4 |
| 1,2,3 | 43,62,37 | 3 | 2,1,3 |
The only problem is that the ranking Values increase from 1 to 9 instead of ranking each row uniquely. Its there any idea that can help me cross over and fix this? I would be grateful for your help. Thanks

MySQL select from two column table

i have a table with only 2 columns.
for example
table product.combinations
Column 1: product.id
Column 2: attribute.id
Product.id is unique
every product can have 1 or more attributes.
Products without attributes are not in the table
for example
table product.combinations
product.id | attribute.id
1 | 1 |
1 | 2 |
2 | 1 |
2 | 2 |
5 | 1 |
5 | 3 |
9 | 2 |
9 | 3 |
9 | 5 |
Now i would like to do a select with the result below
product.id | attribute1 | attribute2 | attribute3 |attribute 4 | attribute 5
1 | 1 | 2 | | |
2 | 1 | 2 | | |
5 | 1 | 3 | | |
9 | 2 | 3 | 5 | |
i have already tried with a pivot but i was not able to hae o good result.
Can anyone give me a help?
First: DO NOT use dots/periods in table/column names, this won't work, use underscores instead.
Second, if it is ok to have all attribute ids in a comma-separated list, you can do the following (using MySQL's GROUP_CONCAT function):
mysql> SELECT
-> product_id, GROUP_CONCAT(attribute_id ORDER BY attribute_id) AS attributes
-> FROM product_combinations
-> GROUP BY product_id
-> ORDER BY product_id;
+------------+---------------+
| product_id | attributes |
+------------+---------------+
| 1 | 1,2 |
| 2 | 1,2 |
| 5 | 1,3 |
| 9 | 2,3,5 |
+------------+---------------+
4 rows in set (0.00 sec)
SELECT ATTRIBUTE
FROM combinations
UNION ALL
SELECT ATTRIBUTE
FROM combinations

Basic SQL query design issue

I'm trying to create a query that would basically be the equivelant of this (does not work).
SELECT * FROM `categories` AS C AND
SELECT * FROM `items` AS I AND
SELECT COUNT(I.id) AS items AND
SELECT SUM(I.price) AS price;
I am not using SQLServer, and I'm using PDO through PHP for database connectivity.
Here's the tables.
Category
+----+------------+
| id | Category |
+----+------------+
| 1 | First_Cat |
| 2 | Second_Cat |
+----+------------+
items
+----+----------+------+-------+
| id | category | name | price |
+----+----------+------+-------+
| 1 | 1 | Foo | 1.99 |
| 2 | 1 | Bar | 2.00 |
| 3 | 2 | ooF | 0.99 |
| 4 | 2 | raB | 1.99 |
+----+----------+------+-------+
Based on these tables I would be expecting these query results:
+----+------------+-------+-------+--+
| id | category | items | price | |
+----+------------+-------+-------+--+
| 1 | First_Cat | 2 | 3.99 | |
| 2 | Second_Cat | 2 | 2.98 | |
+----+------------+-------+-------+--+
Any help?
The query that you have posted in the comment you are not joining the category table and the item table. That makes me think that you could do something like this?:
SELECT
categories.id,
categories.Category,
COUNT(*) AS items,
SUM(items.price) as price
FROM
`categories`
JOIN items
ON categories.id = items.category
GROUP BY
categories.id,
categories.Category

MYSQL: Howto get last download from 2 joined tables

This is my first question, so please be nice :)
I have this:
mysql> select cat_id, cat_name from phpbb_dm_eds_cat;
+--------+----------+
| cat_id | cat_name |
+--------+----------+
| 9 | catx |
| 10 | cat2 |
| 11 | test |
+--------+----------+
mysql> select subcat_id, subcat_name from phpbb_dm_eds_subcat;
+-----------+--------------+
| subcat_id | subcat_name |
+-----------+--------------+
| 39 | aaa |
| 40 | xxx111 |
| 41 | TESTXX |
| 42 | xxa |
+-----------+--------------+
Here is the download table:
mysql> select download_id, download_title, download_cat_id from phpbb_dm_eds;
+-------------+----------------+-----------------+
| download_id | download_title | download_cat_id |
+-------------+----------------+-----------------+
| 3 | s | 9 |
| 5 | raver | 41 |
| 6 | hans | 10 |
| 7 | readme | 42 |
+-------------+----------------+-----------------+
Now the query:
mysql>
SELECT bc.cat_name, bc.cat_id,
COUNT(bd.download_id) AS number_downloads,
MAX(bd.last_changed_time) AS last_download
FROM phpbb_dm_eds_cat bc
LEFT JOIN phpbb_dm_eds bd ON bd.download_cat_id = bc.cat_id
GROUP BY bc.cat_id ;
+----------+--------+------------------+---------------+
| cat_name | cat_id | number_downloads | last_download |
+----------+--------+------------------+---------------+
| catx | 9 | 1 | 1427072549 |
| cat2 | 10 | 1 | 1427125950 |
| test | 11 | 0 | NULL |
+----------+--------+------------------+---------------+
the 'test' category has a subcategory which has a download in the subcat table, the categories 'catx' and 'cat2' have downloads too, there the last download is displayed correctly but i want the last_download in the subcat 'test' to be displayed too
How do I write the query?
You are not clear about what you want but it might be:
SELECT bc.cat_name, bc.cat_id,
COUNT(bd.download_id) AS number_downloads,
MAX(bd.last_changed_time) AS last_download
FROM (
select cat_id, cat_name from phpbb_dm_eds_cat
union
select subcat_id as cat_id, subcat_name as cat_name
from phpbb_dm_eds_subcat
) as bc
LEFT JOIN phpbb_dm_eds bd ON bd.download_cat_id = bc.cat_id
GROUP BY bc.cat_id ;
(Your SELECT is using a MySQL extension, because cat_id is neither in the GROUP BY nor in an aggregate.)
From your notes"the 'test' category has a subcategory" ,i suggest there should be a relation between cat table "phpbb_dm_eds_cat" and sub_cat table
"phpbb_dm_eds_subcat".
Like this:
Table name
phpbb_dm_eds_cat
Columns
(cat_id,cat_name)
Tablename
phpbb_dm_eds_subcat
Columns
(cat_id referencing table phpbb_dm_eds_cat(cat_id),subcat_id,subcat_name)
Sadly your query doesn't work, it gives me ALL subcats, like this:
+----------+--------+------------------+---------------+
| cat_name | cat_id | number_downloads | last_download |
+----------+--------+------------------+---------------+
| catx | 9 | 1 | 1427072549 |
| cat2 | 10 | 1 | 1427125950 |
| test | 11 | 0 | NULL |
| aaa | 39 | 0 | NULL |
| xxx111 | 40 | 0 | NULL |
| TESTXX | 41 | 1 | 1427123713 |
| xxa | 42 | 1 | 1427136789 |
+----------+--------+------------------+---------------+
7 rows in set (0,00 sec)
I don't want the subcats to be displayed, I only want the last download from the subcat, this should be the correct output:
+----------+--------+------------------+---------------+
| cat_name | cat_id | number_downloads | last_download |
+----------+--------+------------------+---------------+
| catx | 9 | 1 | 1427072549 |
| cat2 | 10 | 1 | 1427125950 |
| test | 11 | 1 | 1427213321 |
+----------+--------+------------------+---------------+
3 rows in set (0,00 sec)

Categories