I am writing a complicated website at the moment and I am a bit stuck. I am writing a query that returns the data for the categories of items. I need it to return an array for each category that includes the category name, id and description, along with the number of items that use that category and a value from each item under that category added up.
In other words, I want to return:
categoryid = 1
name = category name
description = category description
totalavailable = number of items in category
totaldownloads = downloads value from each item in category added together.
This is my query so far (it only returns the count and the sum, and they don't really work).
SELECT
category, SUM(downloads) as totaldownloads, count(*) as totalavailable
FROM
downloads
WHERE
category IN(SELECT categoryid FROM categories)
And here is a picture of my schema:
Please help me! I am stuck!
your query is almost perfect, you just have to JOIN both tables to get all values:
SELECT
c.categoryid,
c.name,
c.description,
COUNT(*) AS totalavailable,
SUM(d.downloads) AS totaldownloads
FROM
categories c
INNER JOIN
downloads d
ON
c.categoryid = d.category
WHERE
/* whatever */
GROUP BY
c.categoryid,
c.name,
c.description
Related
I am using MySQL to get some additional information from database. I am trying to do widget bar:
Here is table structure:
My query:
SELECT * FROM `product` WHERE category in (SELECT name FROM category where id='5')
What i want is i need to display category names and products numbers.
But above query gives me empty result set. What am i doing wrong ?
Its only my assumption, since there is little info
This query gets a list of categories and for each adds a count of products having id of that category
select c.id, c.name, count(p.id) count
from category c
left join
product p
on p.category = c.id
group by c.id
You will get rows with category id, category name, product count
Forgive me if I get some terms wrong, still trying to learn advanced mySql queries. I am trying to export data from a ecommerce platform, and some of the data I need is in lookup tables, the issue is the one lookup table I have can have more than 1 value associated, and the system I need to get the data into requires a specific format for that column.
I am using zen cart as my source if that helps, and below is the query.
Select zp.products_id as id, zpd.products_name as name, products_price_w as cost, products_price as price, zp.products_date_added as date_created, zp.products_image as thumbnail
FROM `zen_products` as zp
LEFT JOIN `zen_products_description` as zpd ON zp.products_id = zpd.products_id
WHERE zp.products_status = 1
ORDER BY zp.products_id ASC;
What I need is theres a look up table that tells me what categories belong to each product, I know it's going to be another join, but I need it so if more than 1 category belongs to a product to put it in the same column, and join them with a # symbol, and its not the id's of the category, its the path, so I need to look up the category ID to another table to get the path.
So "category1/subcategory#category2" for example..
Thanks for any guidance.
EDIT: I still need to get the results merged as I am getting double the results I want, but I see a record for each category it's in with this..
Select zp.products_id as id, zpd.products_name as name, zcd.categories_name as categories, products_price_w as cost, products_price as price, zp.products_date_added as date_created, zp.products_image as thumbnail
FROM `zen_products` as zp
INNER JOIN `zen_products_description` as zpd ON zp.products_id = zpd.products_id
INNER JOIN `zen_products_to_categories`as zptc ON zp.products_id = zptc.products_id
INNER JOIN `zen_categories_description` as zcd on zptc.categories_id = zcd.categories_id
WHERE zp.products_status = 1
ORDER BY zp.products_id ASC;
What you are looking for is group_concat(). I think it would be something like this:
Select zp.products_id as id, zpd.products_name as name,
group_concat(zcd.categories_name separator '#') as categories,
products_price_w as cost, products_price as price,
zp.products_date_added as date_created, zp.products_image as thumbnail
FROM `zen_products` as zp
INNER JOIN `zen_products_description` as zpd ON zp.products_id = zpd.products_id
INNER JOIN `zen_products_to_categories`as zptc ON zp.products_id = zptc.products_id
INNER JOIN `zen_categories_description` as zcd on zptc.categories_id = zcd.categories_id
WHERE zp.products_status = 1
group by zp.products_id
ORDER BY zp.products_id ASC;
I couldn't think of the proper way to phrase this and maybe if I knew the correct phrase I could Google it properly but as of yet I am struggling.
I have two tables: categories, directory
On the page where the user selects the category I would like to only show categories where the directory items with that category exist.
I wondered if I could do this with a join and tried
SELECT
wedding_directory_cats.id,
wedding_directory_cats.name,
wedding_directory.id AS d_id
FROM wedding_directory_cats
JOIN wedding_directory ON wedding_directory.category = wedding_directory_cats.id
But this is returning the category for each directory item, so I end up with the same category more than once. Just as I am writing this I'm starting to think I could use GROUP BY at the end but this still means it has to return them all first and then GROUP BY, is that inefficient or is there a better way of doing something like this? Any answers appreciated
Try this:
SELECT wdc.id, wdc.name, wd.id AS d_id
FROM wedding_directory_cats wdc
INNER JOIN (SELECT id, category FROM wedding_directory GROUP BY category) wd ON wdc.id = wd.category ;
OR
SELECT wdc.id, wdc.name, GROUP_CONCAT(wd.id) AS d_id
FROM wedding_directory_cats wdc
INNER JOIN wedding_directory wd ON wdc.id = wd.category
GROUP BY wd.category;
I have a table of Categories, and a table of Products. Products have a category_id, and also a maker_id.
I am attempting to return a table of Category Names, along with a Binary of whether or not the category contains any products that belong to a given $maker_id (as defined in PHP code).
My current method counts how many matching products are in each category, but I'm assuming there is a faster way since I only need a Yes/No. Current code:
SELECT
c.name,
SUM(CASE WHEN p.maker_id = '{$maker_id}' THEN 1 ELSE 0 END) AS already_used
FROM categories c
LEFT JOIN products p ON p.category_id = c.id
GROUP BY c.id
I'm reading up on using EXISTS, but all the examples I've found are using it in the WHERE clause. Thanks!
You can try this:
SELECT c.name,COUNT(1) AS already_used, SUM(IF(p.status = 'ready', 1, 0)) AS ready_count
FROM categories c
LEFT JOIN products p
ON (p.category_id = c.id)
WHERE p.maker_id = '{$maker_id}'
GROUP BY c.id;
In one statement I'm trying to group rows of one table by joining to another table. I want to only get grouped rows where their grouped result is not empty.
Ex. Items and Categories
SELECT Category.id
FROM Item, Category
WHERE Category.id = Item.categoryId
GROUP BY Category.id
HAVING COUNT(Item.id) > 0
The above query gives me the results that I want but this is slow, since it has to count all the rows grouped by Category.id.
What's a more effecient way?
I was trying to do a Group By LIMIT to only retrieve one row per group. But my attempts failed horribly. Any idea how I can do this?
Thanks
Try this:
SELECT item.categoryid
FROM Item
JOIN Category
ON Category.id = Item.categoryId
GROUP BY
item.categoryid
HAVING COUNT(*) > 0
This is similar to your original query, but won't do what you want.
If you want to select non-empty categories, do this:
SELECT category.id
FROM category
WHERE id IN
(
SELECT category_id
FROM item
)
For this to work fast, create an index on item (category_id).
What about eliminating the Category table if you don't need it?
SELECT Item.categoryId
FROM Item
GROUP BY Item.categoryId
I'm not sure you even need the HAVING clause since if there is no item in a category it won't create a group.
I think this is functionally equivalent (returns every category that has at least one item), and should be much faster.
SELECT
c.id
FROM
Category c
WHERE
EXISTS (
select 1 from Item i where i.categoryid = c.categoryID
)
I think, and this is just my opinion, that the correct approach IS counting all the stuff. Maybe the problem is in another place.
This is what I use for counting and it works pretty fast, even with a lot of data.
SELECT categoryid, COUNT(*) FROM Item GROUP By categoryid
It will give you a hash with all the items by category. But it will NOT include empty categories.
Then, for retrieveng category information do like this:
SELECT category.* FROM category
INNER JOIN (SELECT categoryid, COUNT(*) AS n FROM Item GROUP By categoryid) AS item
ON category.id = item.categoryid