I'm trying to count number of items by categories and i want to show 0 on categories with no items
My actual code doen't consider categories with 0 value
SELECT categories.categories_id, categories_name, categories_active, categories_status,
COUNT(IFNULL( product.product_id,0)) as count
FROM categories
LEFT JOIN product ON product.categories_id = categories.categories_id
WHERE categories_status = 1 AND product.active = 1
GROUP BY categories.categories_id
suppose we have two tables categories and products
cat_id cat_name
1 cat A
2 cat B
3 cat C
product_id product_name cat_id
1 prod A 1
2 prod B 2
3 prod C 1
4 prod X 2
i expect to get
cat_id cat_name count products
1 cat A 2
2 cat B 2
3 cat C 0
The problem is that you use
AND product.active = 1
and you filter out null values (categories without products) because of this condition. Try like this:
AND (product.active = 1 OR product.active IS NULL)
final query:
SELECT categories.categories_id, categories_name, categories_active, categories_status,
COUNT(product.product_id) AS count
FROM categories
LEFT JOIN product ON product.categories_id = categories.categories_id
WHERE categories_status = 1 AND (product.active = 1 OR product.active IS NULL)
GROUP BY categories.categories_id
Try using COUNT(*). It counts every row generated by your from/ join / where clauses.
Instead of left join use right join and change the COUNT(IFNULL( product.product_id,0)) to COUNT(product.product_id).Try this once.
SELECT categories.categories_id, categories_name, categories_active, categories_status,
COUNT(product.product_id) as count
FROM categories
RIGHT JOIN product ON product.categories_id = categories.categories_id
WHERE categories_status = 1 AND product.active = 1
GROUP BY categories.categories_id
By right join you will get count 0 data also
Related
I need help with a mysql query using the following two tables:
profiles (TABLE 1)
id user_id gender age height bodytype
1 1 1 57 1 2
2 2 2 32 2 1
profile_lookup (TABLE 2)
id option_group option_value option_name
1 gender 1 Female
2 gender 2 Male
3 gender 3 Prefer not to say
4 height 1 5 ft - 6 in
5 height 2 5ft - 9 in
6 bodytype 1 Petite/slim
7 bodytype 2 Average
There are whole lot of other options and option values that i am omitting for the sake of brevity
I am interested to do inner join queries using the syntax as shown below:
SELECT *
FROM profiles
WHERE bodytype = 2
JOIN profile_lookup
ON profiles.gender = profile_lookup..... (not sure)
Request help with using the correct syntax using the above two tables. Thanks
I think you want:
SELECT p.*, plg.option_name as gender
FROM profiles p INNER JOIN
profile_lookup plg
ON plg.option_group = 'gender' and
plg.option_value = p.gender
WHERE p.bodytype = 2 ;
You can extend this to other columns. You might want a LEFT JOIN in case some values don't match (i.e. are NULL):
SELECT p.*, plg.option_name as gender, plh.option_name as height
FROM profiles p LEFT JOIN
profile_lookup plg
ON plg.option_group = 'gender' AND
plg.option_value = p.gender LEFT JOIN
profile_lookup plh
ON plh.option_group = 'height' AND
plh.option_value = p.height
WHERE p.bodytype = 2
The where clause should be after the JOIN clause
SELECT * FROM profiles
INNER JOIN profile_lookup ON profiles.gender = profile_lookup.option_value
and profile_lookup.option_group = 'gender'
WHERE profiles.bodytype = 2
and for the join you need the proper profile_lookup.option_value
I have many to many relation
table: images
id imageName
1 pic01
2 pic02
3 pic03
table: imagesKeywords
imageId keywordId
1 2
1 3
1 4
2 3
3 1
3 4
3 2
table: keywords
id keywordName
1 car
2 tree
3 cat
4 phone
Each image has some keywords, and different images can have the same keyword.
I need to make a search for images , they have a specific keywordName's.
example-1: search for car and phone
the result should be : pic03
example-2: search for tree and phone
the result should be : pic01, pic03
You appear to want JOIN with GROUP BY Clause :
select i.imageName
from images i inner join
imagesKeywords ik
on ik.imageId = i.id inner join
keywords k
on k.id = ik.keywordId
where k.keywordName in ('car', 'phone')
group by i.imageName
having count(*) = 2;
As I understand you, this should work:
select i.imageName as name from keywords k
join imagesKeywords iK on k.id = iK.keywordId
join images i on iK.imageId = i.id
group by i.imageName;
One possible solution,
with subquery as
(select i1.imageName, k1.keywordName from keywords k1 join imagekeywords ik1 on k1.id=ik1.keywordId join images i1 on i1.id = ik1.imageId )
select a.imageName from subquery a join subquery b on a.imageName=b.imageName where a.keywordName ='car' and b.keywordName='phone';
I am having trouble with coming up with the query required to do what I am after.
I have three tables like this:
client_files
-----------------------
client_id file_id
-----------------------
1 2
1 3
1 6
2 1
2 2
3 5
files
-------------------------------------------------
ID file_name file_category_id
-------------------------------------------------
1 file1.ext 1
2 file2.ext 3
3 file3.ext 1
4 file4.ext 1
5 file5.ext 2
6 file6.ext 2
file_categories
--------------------------
ID category_name
--------------------------
1 category1
2 category2
3 category3
I am attempting to build a query which will return the filename and category name for a particular client ID.
The result I am expecting is (from ID 1):
-----------------------------
file_name category_name
-----------------------------
file2.ext category3
file3.ext category1
file6.ext category2
As far as I understand it, I need to join the client_files table to the files table and then to the file_categories table. I've looked at other examples which are about joining two tables with a 3rd table linking them together, but believe this is a different situation.
This is the equivalent of what I have come up with, but the results are almost random, with some files returned that are not linked, and some are missing.
SELECT
f.file_name,
fc.category_name
FROM
client_files cf,
files f,
file_categories fc
WHERE
cf.client_id = 1 AND f.ID = cf.file_id AND fc.ID = f.file_category_id;
You can do it in two ways, but i thing essentially it's the same.
The first way:
SELECT
f.file_name,
fc.category_name
FROM
client_files cf
JOIN files f ON cf.file_id = f.id
JOIN file_categories fc ON fc.id = f.file_category_id
Or, the second way:
SELECT
f.file_name,
fc.category_name
FROM
(client_files cf
JOIN files f ON cf.file_id = f.id) data1
JOIN file_categories fc ON fc.id = data1.file_category_id
You need to have proper join conditions, right now you are doing cross join and then having the where condition.
SELECT
cf.client_id,
f.file_name,
fc.category_name
FROM
client_files cf
LEFT JOIN
files f ON cf.file_id = f.ID
LEFT JOIN
file_categories fc ON fc.ID = f.file_category_id
WHERE
cf.client_id = 1;
Try this query:
SELECT files.file_name, file_categories.category_name
FROM ((files LEFT JOIN client_files ON files.ID = client_files.file_id)
LEFT JOIN file_categories ON files.file_category_id = file_categories.ID)
WHERE client_files.client_id = 1
I have 2 tables
TBL 1: property TBL 2: property_detail
--------------------- --------------------------------------
Id Name status property_id param value
--------------------- --------------------------------------
1 X 1 1 parking two-wheeler
2 Y 1 1 furnishing furnished
3 Z 0 2 parking car-parking
4 A 1 2 furnishing semi-furnished
5 B 1 3 furnishing furnished
6 C 0 4 parking car-parking
"property_id" column in "property_detail" is foreign key of "Id" column in "property"
I want search result for status=1 and (param="parking" and value="car-parking") and (param="furnishing" and value="furnished")
From above Example table, the result will be
Result
-------------
id name
-------------
2 Y
How to achieve this?
you can get your desired result set by using join twice with details table
select p.*
from property p
join property_detail d on (p.Id = d.property_id)
join property_detail d1 on (p.Id = d1.property_id)
where p.status=1
and d.param='parking' and d.value='car-parking'
and d1.param='furnishing' and d1.value='semi-furnished';
Another way you can also use below query using having clause and sum function
select p.*
from property p
join property_detail d on (p.Id = d.property_id)
where p.status=1
group by p.Id
having sum(param="parking" and value="car-parking")
and sum(param="furnishing" and value="semi-furnished")
DEMO
SELECT property.id, property.name
FROM property INNER JOIN property_detail
ON property.id = property_detail.property_id
WHERE
(`param`="parking" AND `value`="car-parking")
AND
(`param`="furnishing" AND `value`="furnished")
AND status = 1;
can you try this one? I'm not sure though.. but it'll give you an idea.
I have the 3 Following Tables:
objects:
ObjectID ObjectDescription
1 "first"
2 "second"
attributes:
AttributeID AttributeDescription
1 "att1"
2 "att2"
3 "att3"
4 "att4"
attributelink:
AttributeID ObjectID
1 1
2 1
4 1
Now my question: I want now have some attributes selected and want to know, which Object has all my selected Attributes. I've tried the following:
SELECT * FROM `objects`
INNER JOIN `attributelink`
ON `objects`.`ObjectID` = `attributelink`.`ObjectID`
WHERE `attributelink`.`AttributeID` =1 AND `attributelink`.`AttributeID` =2
GROUP BY `objects`.`ObjectID`
That obviously doesn't work, because one row can't have 2 AttributeIDs, but how can I archieve this?
You have to join on the attributelink table once for each selected attribute you want to check for:
SELECT o.ObjectID
FROM objects o
INNER JOIN attributelink a1 ON o.ObjectID = a1.ObjectID AND a1.AttributeID = 1
INNER JOIN attributelink a2 ON o.ObjectID = a2.ObjectID AND a2.AttributeID = 2
GROUP BY o.ObjectID
Your test data doesn't show a whole lot about whether it works or not, but FWIW, here's the sqlfiddle.
Another way to do it is to use COUNT DISTINCT with HAVING and GROUP BY (sqlfiddle):
SELECT o.ObjectID
FROM objects o
INNER JOIN attributelink a ON o.ObjectID = a.ObjectID
WHERE a.AttributeID IN (1,2) --here you filter the rows on the attributes to test
GROUP BY o.ObjectID
HAVING COUNT(DISTINCT(a.AttributeID)) = 2 --# of attributes, means "having ALL"