Mysql query based on category - mysql

Hi i have 3 tables as follow:
business:
business_id business_name cat_id sub_cat_id
1 bz1 1 1001
2 bz2 1 1005
3 bz3 2 2001
4 bz4 1 1001
business_category:
cat_id cat_name
1 Restaurant
2 Food
3 Travel
business_sub_category:
b_sub_cat_id b_subcat_name b_maincat_id
1001 Italian 1
1002 French 1
1003 Asian 1
2001 Bagels 2
Now my query seems not work well when i want to find business based on b_subcat_name using like. This are my query:
SELECT `b`.`business_name`, `b`.`cat_id`, `b`.`business_id`, `bc`.`cat_name`, `bsc`.`b_subcat_name`, `bsc`.`b_sub_cat_id` FROM `business` AS `b` INNER JOIN `business_category` AS `bc` ON b.cat_id = bc.cat_id INNER JOIN `business_sub_category` AS `bsc` ON b.sub_cat_id = bsc.b_sub_cat_id WHERE (bc.cat_name like 'italian%') OR (bc.cat_name like '%italian') OR (bc.cat_name = 'italian')
Thanks!

I think you should using b_subcat_name in WHERE clause, because no cat_name has value contains Italy
Try to change this:
SELECT `b`.`business_name`, `b`.`cat_id`, `b`.`business_id`, `bc`.`cat_name`, `bsc`.`b_subcat_name`, `bsc`.`b_sub_cat_id` FROM `business` AS `b` INNER JOIN `business_category` AS `bc` ON b.cat_id = bc.cat_id INNER JOIN `business_sub_category` AS `bsc` ON b.sub_cat_id = bsc.b_sub_cat_id WHERE (bc.cat_name like 'italian%') OR (bc.cat_name like '%italian') OR (bc.cat_name = 'italian')
to
SELECT `b`.`business_name`, `b`.`cat_id`, `b`.`business_id`, `bc`.`cat_name`, `bsc`.`b_subcat_name`, `bsc`.`b_sub_cat_id` FROM `business` AS `b` INNER JOIN `business_category` AS `bc` ON b.cat_id = bc.cat_id INNER JOIN `business_sub_category` AS `bsc` ON b.sub_cat_id = bsc.b_sub_cat_id WHERE (bsc.b_subcat_name like 'italian%') OR (bsc.b_subcat_name like '%italian') OR (bsc.b_subcat_name = 'italian')

Related

How to return customers and additional info who have null in second table

T1 Customers
IDZ NAME MEGAID
123 TOM 32132
124 JEK 32323
125 MAX 32342
126 JIZ 32134
T2 Info:
ID CID GUNS STATUS
1 123 3 1
2 124 4 2
3 126 NULL 1
T3 Status:
ID TYPE
1 Active
2 Inactive
IDZ = CID
I need to return NAME, MEGAID and STATUS (Active/Inactive) for everyone who have NULL on GUNS column from INFO table.
I tried this:
SELECT Customers.Name, CustomersMEGAID, Status.TYPE
FROM Customers
LEFT JOIN Customers ON Info.CID=Custoners.IDZ
WHERE Info.Guns= IS NULL;
But thats doesnt work(
Big thanks if someone can help with this
your question is full with errors but here is a query for you:
SELECT Customers.Name, Customers.MEGAID, Status.TYPE
FROM Customers
LEFT JOIN Info ON Customers.IDZ = Info.CID
INNER JOIN Status ON Info.STATUS = Status.ID
WHERE Info.Guns IS NULL;
You can join all three tables, and then search for nulls in the column.
For example:
select
c.name,
c.megaid,
s.type
from customers c
join info i on i.cid = c.idz
join status s on s.id = i.status
where i.guns is null

SQL query from many to many relation

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';

MySQL One to Many remove specific 'many'

I have a database with a one to many relationship (venues, with associated categories) like so:
venue_id | venue_name
---------------------
1 | venue1
2 | venue2
and categories
venue_id | category_id
---------------------
1 | 5
2 | 7
1 | 8
2 | 5
I want to show all venues that HAVE category_id of 5, but dont have category_id of 7 and 8. I tried using a join like so:
SELECT distinct(`venue_to_category`.`venue_id`),`venue_name`
FROM `venue_to_category` INNER JOIN `venues`
ON `venues`.venue_id = `venue_to_category`.venue_id
WHERE `category_id` != 7
AND `category_id` != 8
AND `category_id` = 5
But it is not returning the correct results (in fact I am unsure the results it is returning)
2 Things in your case
Get data where category_id = 5 and not 7 or 8
Get data where category_id = 5 and not both 7 and 8
For the first one you can use
select
v.venue_id,
v.venue_name
from venues v
join categories c on c.venue_id = v.venue_id
where c.category_id = 5
AND NOT EXISTS
(
select 1 from categories c1 where v.venue_id = c1.venue_id
AND c1.category_id in (7,8)
);
For the 2nd one
select
v.venue_id,
v.venue_name
from venues v
join categories c on c.venue_id = v.venue_id
where c.category_id = 5
AND NOT EXISTS
(
select 1 from categories c1 where v.venue_id = c1.venue_id
AND c1.category_id in (7,8) having count(*) = 2
);
DEMO
When doing a search function of your site. Match and Against is better than Like sql statement. The field must be set to FullText match the term on the field:
SELECT vc.venue_id, venue_name FROM venue_to_category vc, venues v WHERE MATCH(category_id) AGAINST('-7 -8 +5');
You can also use the IN BOOLEAN MODE to allow operators in the sql statement. eg. ...
MATCH(category_id) AGAINST('-7 -8 +5' IN BOOLEAN MODE) ...
(-) minus sign that means nothing should match '-7' '-8'
(+) the word must be present in the match.
There are many other operators to be used. Refer to this page for more operator and explanation
Try
SELECT distinct `venue_to_category`.`venue_id` ,`venue_name`
FROM `venue_to_category` INNER JOIN `venues`
ON `venues`.venue_id = `venue_to_category`.venue_id
WHERE `category_id` <> 7
AND `category_id` <> 8
AND `category_id` = 5
or
SELECT distinct `venue_to_category`.`venue_id` ,`venue_name`
FROM `venue_to_category` INNER JOIN `venues`
ON `venues`.venue_id = `venue_to_category`.venue_id
WHERE `category_id` NOT IN (7,8)
AND `category_id` = 5
Note: distinct is not a function. And for your example you could leave it out entirely, because there are no duplicate rows.
SELECT v.id, v.name
FROM venues v
JOIN venue_to_category vc
ON vc.venue_id=v.id
AND vc.category_id=5
WHERE NOT EXISTS (
SELECT 1
FROM venue_to_category vci
WHERE vci.venue_id = v.id
AND vci.category_id IN (7,8)
);

MySql Join - How to get all rows besides related? HowTo SUM within a Joined Table?

I have 3 Tables (with prefix "pindex_")
names photos link
id, name id, filename photo_id, name_id
-------- ------------ -----------------
1 , leo 1 , aa.jpg 1 , 1
2 , liz 2 , bb.jpg
3 , ann
So Leo is connected to Photo aa.jpg
Now I would like to get all names that are not connected to aa.jpg.
Result should be: Liz (2), Ann (3).
I have tried with this but it isn't working so far:
select nm.name from pindex_names nm
join pindex_link pl on pl.name_id = nm.id
join pindex_photos pp on pl.photo_id = pp.id
where pl.name_id !='$id'
And my second question is how i can SUM up a Col within a joined table?
For exaple I would like to Count how many names are connected to a certain photo.
Here is one method:
select n.*
from names n
where not exists (select 1
from link l join
photos p
on l.photo_id = p.id
where l.name_id = n.id and
p.filename = 'aa.jpg'
);
SELECT *
FROM pindex_names
WHERE id NOT IN
(
SELECT name_id
FROM pindex_link pl
INNER JOIN pindex_photos pp
ON pl.photo_id = pp.id
WHERE filename='aa.jpg'
)

SQL Query -- Student Weighted Grade Calculation

I am having trouble calculating students grades together to get their final grade.
I have the following tables
Students
----------------
stu_id
stu_fname
stu_lname
Grades
----------------
grade_id
grade_name
grade_type
grade_possible
StudentGrades
-----------------
stu_grade_id
grade_id
stu_id
grade_earned
GradeTypes
----------------
grade_type
grade_type_name
grade_weight
This is the query that I have been able to come up with
Select S.stu_fname, S.stu_lname, GT.grade_type_name,
(ROUND((SUM(SG.grade_earned)/SUM(G.grade_possible)), 2) * ROUND((GT.grade_weight/100.0)
, 2) ) as CalculatedGrade
FROM Student S
INNER JOIN StudentGrade SG on SG.stu_id = S.stu_id
INNER JOIN Grade G on SG.grade_id = G.grade_id
INNER JOIN GradeType GT WHERE G.grade_type = GT.grade_type
GROUP BY S.stu_fname, S.stu_lname, GT.grade_type_name;
I get the query report below
James | Fort | HW/QUIZ | 30.0
James | Fort | LogBook | 60.0
Robin | Hood | HW/QUIZ | 60.0
Robin | Hood | Logbook | 25.0
I want to be able to add both of James Forts grades together to get his final grade and the same for Robin Hood.
Any help is appreciated, I am stuck at this point. I am almost done. I have researched sub queries and need more help to narrow my search to get the answer.
Have you tried the following ?
SELECT results.stu_fname, results.stu_lname, sum(results.CalculatedGrade)
FROM(
SELECT S.stu_fname, S.stu_lname, GT.grade_type_name,
(ROUND((SUM(SG.grade_earned)/SUM(G.grade_possible)), 2) * ROUND((GT.grade_weight/100.0)
, 2) ) as CalculatedGrade
FROM Student S
INNER JOIN StudentGrade SG on SG.stu_id = S.stu_id
INNER JOIN Grade G on SG.grade_id = G.grade_id
INNER JOIN GradeType GT WHERE G.grade_type = GT.grade_type
GROUP BY S.stu_fname, S.stu_lname, GT.grade_type_name
)results
GROUP BY results.stu_fname, results.stu_lname;
Edit: added aliases thanks to AshReva's remark.
Well, just remove GT.grade_type_name from the select and group by. Does this do what you need?
Select S.stu_fname, S.stu_lname,
(ROUND((SUM(SG.grade_earned)/SUM(G.grade_possible)), 2) * ROUND((GT.grade_weight/100.0)
, 2) ) as CalculatedGrade
FROM Student S INNER JOIN
StudentGrade SG
on SG.stu_id = S.stu_id INNER JOIN
Grade G
on SG.grade_id = G.grade_id INNER JOIN
GradeType GT
on G.grade_type = GT.grade_type
GROUP BY S.stu_fname, S.stu_lname;