I have the following tables
Dishes table:
Category table:
t_time table:
To get connect a dish with the ingredients I have the following code which works:
$sql = "SELECT d.name, i.item\n"
. "FROM dish d\n"
. "JOIN dish_ingredients di ON ( d.id = di.dish_id )\n"
. "JOIN ingredients i ON ( di.ingredient_id = i.id )\n"
. "WHERE d.id =1\n"
. "LIMIT 0 , 30";
but now I want to connect the dish with the matching categories/t_time and cuisine . instead of having time= 6 and Category 3 being displayed when I do the query I want it to display 60 and fish instead. What would be the easiest way to do this? a good tutorial might help as well.
just join the tables just like the way you are doing.
SELECT d.name, i.item,
c.category,
e.cuisine,
f.t_time
FROM dish d
INNER JOIN dish_ingredients di ON ( d.id = di.dish_id )
INNER JOIN ingredients i ON ( di.ingredient_id = i.id )
INNER JOIN categories c ON (d.category = c.id)
INNER JOIN cuisine e ON d.cuisine = e.id
INNER JOIN t_time f ON d.time = f.id
WHERE d.id =1
-- LIMIT 0 , 30
If it is possible that a dish can have nullable values on category, cuisine, and t_time, use LEFT JOIN instead of INNER JOIN. Basically, INNER JOIN displays row on which it has at least one match on the table on which you have joined while the LEFT JOIN displays even if it has no rows on the other table.
Try this:
SELECT d.name, i.item, cat.category, t.t_time, cu.cuisine
FROM dish d
INNER JOIN dish_ingredients di ON d.id = di.dish_id
INNER JOIN ingredients i ON di.ingredient_id = i.id
INNER JOIN category cat ON d.category = cat.id
INNER JOIN cuisine cu ON d.cuisine = cu.id
INNER JOIN t_time t ON d.t_time = t.id
WHERE d.id = 1
$sql = "SELECT d.name, i.item, c.category, t.t_time, cs.cuisine\n"
. "FROM dishes d\n"
. "JOIN dish_ingredients di ON ( d.id = di.dish_id )\n"
. "JOIN ingredients i ON ( di.ingredient_id = i.id )\n"
. "LEFT JOIN category c ON ( c.id = d.category )\n"
. "LEFT JOIN t_time t ON ( t.id = d.t_time )\n"
. "LEFT JOIN cuisine cs ON ( cs.id = d.cuisine)\n"
. "WHERE d.id =1\n"
. "LIMIT 0 , 30";
Try to join to the tables with LEFT JOIN, it will show the category,t_time and cuisine if it exists.
Related
So I'm a total newbie trying to solve this exercise where I have to find all the dishes that are marked as Vegetarian but contain Turkey meat in their ingredients.
This is what I've tried (this is where I inner join 3 tables to find the ingredients):
SELECT Name
FROM Dishes
INNER JOIN DishesIngredients ON DishesIngredients.DishId = s.Id
INNER JOIN Ingredients ON DishesIngredients.IngredientID = Ingredients.ID
this is where I can't seem to be able to join the subquery to identify the Vegetarian tag:
WHERE Ingredients.Name = 'Turkey meat' =
(SELECT Name
FROM Tags
INNER JOIN DishesTags ON DishesTags.TagID = Tags.ID
INNER JOIN Dishes ON DishesTags.DishID = Dishes.ID)
The diagram of the database is here for reference:
Let first find out how many dishes have Turkey meat as ingredient.
You have:
SELECT D.ID
FROM
Dishes D
JOIN DishIngredients DI ON D.ID = DI.DishID
JOIN Ingredients I ON DI.IngredientID = I.ID
WHERE I.Name LIKE 'Turkey meat'
Then get all dishes with tag 'Vegetarian'.
SELECT D.ID
FROM
Dishes D
JOIN DishIngredients DI ON D.ID = DI.DishID
JOIN Ingredients I ON DI.IngredientID = I.ID
JOIN DishesTags DT on D.ID = DT.DishID
JOIN Tags T ON DT.TagID = T.ID
WHERE I.Name LIKE 'Turkey meat'
AND T.Name = 'Vegetarian'
You could use exists and subqueries:
select d.*
from dishes d
where
exists (
select 1
from dishestags dt
innerjoin tags t on t.id = dt.tagid
where dt.dishid = d.id and t.name = 'Vegetarian'
)
and exists (
select 1
from dishesingredients di
inner join ingredients i on i.id = di.ingredientid
where di.dishid = d.id and i.name = 'Turkey'
)
I tried to make query in cakephp with joins, but i want to get more fileds,
Here the query sql :
SELECT
sd.debut,
sd.fin,
fr.id,
f.id as formtaion_id,
s.id as seance_id,
fr.nom as formateur,
f.nom as formation,
r.title,
f.module,
sd.module as partie ,
f.couleur
FROM seances s
INNER JOIN formations f on s.formation_id = f.id
INNER JOIN seances_dates sd on s.id = sd.seance_id
INNER JOIN salles sa on sa.id = s.salle_id
INNER JOIN regions r on r.id = sa.region_id
INNER JOIN presence_formateurs pf ON pf.seance_id = s.id
INNER JOIN formateurs fr ON fr.id = pf.formateur_id
WHERE fr.archived = 0
AND fr.deleted is null
AND (
(sd.debut between '".$from."' and '".$to."')
OR
(sd.fin between '".$from."' and '".$to."')
)
GROUP BY sd.id
ORDER BY sd.debut
please help me to make that query in cakephp :
ClassRegistry::init('seance')->find('all'....
You should read very carefully
1. How to Retrieve data in CakePHP and
2. How to make Relation with different table
I am trying to retrieve the right count of records to mitigate an issue I am having. The below query returns 327 records from my database:
SELECT DISTINCT COUNT(at.someid) AS CountOfStudentsInTable FROM tblJobSkillAssessment AS at
INNER JOIN tblJobSkills j ON j.jobskillid = at.skillid
LEFT JOIN tblStudentPersonal sp ON sp.someid2 = at.someid
INNER JOIN tblStudentSchool ss ON ss.monsterid = at.someid
INNER JOIN tblSchools s ON s.schoolid = ss.schoolid
INNER JOIN tblSchoolDistricts sd ON sd.schoolid = s.schoolid
INNER JOIN tblDistricts d ON d.districtid = sd.districtid
INNER JOIN tblCountySchools cs ON cs.schoolid = s.schoolid
INNER JOIN tblCounties cty ON cty.countyid = cs.countyid
INNER JOIN tblRegionUserRegionGroups rurg ON rurg.districtid = d.districtid
INNER JOIN tblGroups g ON g.groupid = rurg.groupid
WHERE ss.graduationyear IN (SELECT Items FROM FN_Split(#gradyears, ',')) AND sp.optin = 'Yes' AND g.groupname = #groupname
Where I run into trouble is trying to reconcile that with the below query. One is for showing just a count of all the particular students the other is showing pertinent information for a set of students as needed but the total needs to be the same and it is not. The below query return 333 students - the reason is because the school the student goes to is in two separate counties and it counts that student twice. I can't figure out how to fix this.
SELECT DISTINCT #TableName AS TableName, d.district AS LocationName, cty.county AS County, COUNT(DISTINCT cc.monsterid) AS CountOfStudents, d.IRN AS IRN FROM tblJobSkillAssessment AS cc
INNER JOIN tblJobSkills AS c ON c.jobskillid = cc.skillid
INNER JOIN tblStudentPersonal sp ON sp.monsterid = cc.monsterid
INNER JOIN tblStudentSchool ss ON ss.monsterid = cc.monsterid
INNER JOIN tblSchools s ON s.schoolid = ss.schoolid
INNER JOIN tblSchoolDistricts sd ON sd.schoolid = s.schoolid
INNER JOIN tblDistricts d ON d.districtid = sd.districtid
INNER JOIN tblCountySchools cs ON cs.schoolid = s.schoolid
INNER JOIN tblCounties cty ON cty.countyid = cs.countyid
INNER JOIN tblRegionUserRegionGroups rurg ON rurg.districtid = d.districtid
INNER JOIN tblGroups g ON g.groupid = rurg.groupid
WHERE ss.graduationyear IN (SELECT Items FROM FN_Split(#gradyears, ',')) AND sp.optin = 'Yes' AND g.groupname = #groupname
GROUP BY cty.county, d.IRN, d.district
ORDER BY LocationName ASC
If you just want the count, then perhaps count(distinct) will solve the problem:
select count(distinct at.someid)
I don't see what at.someid refers to, so perhaps:
select count(distinct cc.monsterid)
I have the following two queries below, the Total is coming back different, but I am adding the sums in each of the query the same way. Why is the total coming back different?
select [Total Children] = (SUM(demo.NumberOfPreschoolers) + SUM(demo.NumberOfToddlers) + SUM(demo.NumberOfInfants)),
County = co.Description
from ClassroomDemographics as demo
inner join Classrooms as c on demo.Classroom_Id = c.Id
inner join Sites as s on c.Site_Id = s.Id
inner join Profiles as p on s.Profile_Id = p.Id
inner join Dictionary.Counties as co on p.County_Id = co.Id
where co.Description = 'MyCounty'
Group By co.Description
select [Number Of DLL Children] = SUM(cd.NumberOfLanguageSpeakers),
[Total Children] = (SUM(demo.NumberOfPreschoolers) + SUM(demo.NumberOfToddlers) + SUM(demo.NumberOfInfants)),
County = co.Description
from ClassroomDLL as cd
inner join Classrooms as c on cd.Classroom_Id = c.Id
inner join Sites as s on c.Site_Id = s.Id
inner join Profiles as p on s.Profile_Id = p.Id
inner join Dictionary.Counties as co on p.County_Id = co.Id
inner join ClassroomDemographics as demo on c.Id = demo.Classroom_Id
where co.Description = 'MyCounty'
Group by co.Description
Just a quick glance over the two querties, I would presume that:
inner join ClassroomDemographics as demo on c.Id = demo.Classroom_Id
in the second query is excluding results that are in the first query, therefor the aggregated values will be different.
Your join to the Classrooms table is joining with an extra table in the 2nd query.
Query 1:
from ClassroomDemographics as demo
inner join Classrooms as c on demo.Classroom_Id = c.Id
Query 2:
from ClassroomDLL as cd
inner join Classrooms as c on cd.Classroom_Id = c.Id
...
inner join ClassroomDemographics as demo on c.Id = demo.Classroom_Id
My bet is that the ClassroomDLL table has less data in it, or has rows with a null for one of the join criteria columns, either of which could exclude rows from the results and throw your aggregate totals off.
Is it possible to use a select in the middle of joining...
I am trying to do the following:
FROM
tblorders o
INNER JOIN tblunits u on o.id = u.orderid
INNER JOIN ((SELECT
,Min(n.date) as [MinDate]
from tblNotes n
Where n.test = 'test') te
INNER JOIN tblnotes n on te.id = n.id
and te.[MinDate] = n.AuditinsertTimestamp)
INNER Join tblClient c ON o.ClientId = c.Id
Basically in the select in the middle of the query it is selecting only the notes with min date. The problem is I need to do this here because I need from tblOrders to be the first table.......
Suggestions?
The INNER JOIN failed because you have a leading comma here:
,Min(n.date) as [MinDate]
I think you are looking for something like this:
SELECT ...
FROM tblorders o
INNER JOIN tblunits u on o.id = u.orderid
INNER JOIN (
SELECT id, Min(date) as [MinDate]
from tblNotes
Where test = 'test'
group by id
) te <-- not sure what JOIN clause to use here, please post schema
INNER JOIN tblnotes n on te.id = n.id
and te.[MinDate] = n.AuditinsertTimestamp
INNER Join tblClient c ON o.ClientId = c.Id
You are missing an alias and join condition:
FROM
tblorders o
INNER JOIN tblunits u on o.id = u.orderid
INNER JOIN ((SELECT Min(n.date) as [MinDate]
from tblNotes n
Where n.test = 'test') te
INNER JOIN tblnotes n on te.id = n.id
and te.[MinDate] = n.AuditinsertTimestamp)
-- missing
AS z
ON <join conditions haere>
INNER Join tblClient c ON o.ClientId = c.Id
Yes, you can have a Select in a Join.