I have this query:
SELECT w.windate, w.wintime, w.field, w.htname, w.vtname, w.plateumpire,
w.fieldumpire1, w.fieldumpire2, w.fieldumpire3, p.pteamname, p.teamcoach,
p.pteamdivision, d.originalid
FROM sportsdb_wins AS w, playerteams AS p, sportsdb_divs AS d
WHERE p.teamcoach='$coachid'
AND p.pteamname IN (w.htname, w.vtname)
AND p.forteam='$teamid'
and at least one of the rows is returned 3 times! Why? Please help I am a SQL novice.
Using this in PHP...
Use JOIN's when you have to join the tables. Your current problem is a so called cartesian product.
You have no join condition defined for the sportsdb_divs table, so you're getting a cross product of those results. This would be more obvious if you used explicit joins (which you should be doing in all of your SQL code).
SELECT w.windate, w.wintime, w.field, w.htname, w.vtname, w.plateumpire,
w.fieldumpire1, w.fieldumpire2, w.fieldumpire3, p.pteamname, p.teamcoach,
p.pteamdivision, d.originalid
FROM playerteams AS p
INNER JOIN sportsdb_wins AS w
ON p.teamname in (w.htname, w.vtname)
INNER JOIN sportsdb_divs AS d
ON ?????
WHERE p.teamcoach='$coachid'
AND p.forteam='$teamid'
Related
I am trying to make a "recipe" system inside a game. The player can own a company and craft items in there.
I currently fetch the recipes per company type but I don't know how to write the query in a way that I can also fetch the item names and images if the item_id is not empty.
This is working:
SELECT a.recipe_id,
a.item1_id,
a.item1_uses,
a.item2_id,
a.item2_uses,
a.item3_id,
a.item3_uses,
a.item4_id,
a.item4_uses,
a.item5_id,
a.item5_uses,
a.newitem_id,
a.newitem_uses,
a.craft_description,
a.craft_button
FROM
company_recipes AS a,
company_types AS b
WHERE
a.type_id = b.type_id
AND
b.type_id = '".$type."';
"
A recipe can contain for example two items needed to craft something new, but it could also be 5. So if it's only 2, I only want to fetch the img, name of these 2 and the rest can be skipped.
I have a different table store_items that contains the img and name of the item. I was thinking something along the lines of an IF ELSE or CASE WHEN inside the query, but I'm not sure how I'd do that.
Something like: SELECT c.img, c.name FROM store_items AS c IF a.item1_id is not NULL.
I feel like I'm close to the solution, but missing the last step.
Thanks for the tips #jarlh, I've changed the code and came to this result. If you have any more tips to do it better I'm happy to listen. (I'm still a junior and thought myself by trial and error, so I might not have the best solutions at times... Which is why tips are highly appreciated).
SELECT cr.recipe_id,
cr.item1_id,
cr.item1_uses,
si1.name,
si1.img,
cr.item2_id,
cr.item2_uses,
si2.name,
si2.img,
cr.item3_id,
cr.item3_uses,
si3.name,
si3.img,
cr.item4_id,
cr.item4_uses,
si4.name,
si4.img,
cr.item5_id,
cr.item5_uses,
si5.name,
si5.img,
cr.newitem_id,
cr.newitem_uses,
si_new.name,
si_new.img,
cr.craft_description,
cr.craft_button
FROM
company_recipes AS cr
INNER JOIN company_types AS ct ON cr.type_id = ct.type_id
LEFT JOIN store_items AS si1 ON cr.item1_id = si1.item_id
LEFT JOIN store_items AS si2 ON cr.item2_id = si2.item_id
LEFT JOIN store_items AS si3 ON cr.item3_id = si3.item_id
LEFT JOIN store_items AS si4 ON cr.item4_id = si4.item_id
LEFT JOIN store_items AS si5 ON cr.item5_id = si5.item_id
LEFT JOIN store_items AS si_new ON cr.newitem_id = si_new.item_id
WHERE
ct.type_id = '".$type."';
I'm basically fetching everything now and handle the NULLs in the php code now.
Without seeing more info its had to see what you are trying achieve but you could start by using the the users inpute of the game to determine what data is first required before futher filtering. Try this:
Declare #Value int
set #Value = #User_input --- uses what ever the game user will
SELECT
a.recipe_id,
a.item1_id,
a.item1_uses,
a.item2_id,
a.item2_uses,
a.item3_id,
a.item3_uses,
a.item4_id,
a.item4_uses,
a.item5_id,
a.item5_uses,
a.newitem_id,
a.newitem_uses,
a.craft_description,
a.craft_button
--- you can insert more columns but i stopped here as i dont know what data you have in the other tables.
FROM
company_recipes a
INNER JOIN company_types b ON a.type_id = b.type_id
INNER JOIN store_items c ON c.type_id = b.type_id
WHERE
b.type_id = #Value; --- '".$type."';
I got the bellow piece of select statement that got level 2 child records, having problems to got deeper, can anyone help out?
SELECT
id_mobile AS ID_PROJETO,
UM.qtd_UC,
AM.qtd_AMBIENTE
FROM projetos_mobile AS PM
LEFT JOIN (
SELECT
COUNT(id) AS qtd_UC,
projeto,
data_hora_importacao,
id_uc_mobile
FROM ucs_mobile
WHERE data_hora_importacao = '2015-05-15 17:21:02'
GROUP BY projeto) AS UM
ON PM.id_mobile = UM.projeto
LEFT JOIN (
SELECT
COUNT(id_uc_mobile) AS qtd_AMBIENTE,
id_uc_mobile
FROM ucs_mobile
LEFT JOIN (
SELECT
uc
FROM ambientes_mobile AS s
WHERE data_hora_importacao = '2015-05-15 17:21:02') AS G
ON G.uc = ucs_mobile.id_uc_mobile
WHERE data_hora_importacao = '2015-05-15 17:21:02') AS AM
ON UM.id_uc_mobile = AM.id_uc_mobile
WHERE PM.data_hora_importacao = '2015-05-15 17:21:02'
http://sqlfiddle.com/#!9/2eecf
here is a sqlfiddle if anyone want to try a solution. I have the specific hierarchy: projeto>uc>ambiente>secao>medicoes
ucs_mobile.projeto refers to projetos_mobile.id_mobile
ambientes_mobile.uc refers to ucs_mobile.id_uc_mobile
secoes_iluminacao_mobile.ambiente refers to ambientes_mobile.id_ambiente_mobile
I need a count of each child for the parent I pass, I will have 5 functions that
return the count of each child for a given parent, for example, for a projeto parent I should have count(ucs),count(ambientes),count(secoes),count(medicoes)
So, hope you guys can help me. The database is terrible ugly but that's is what I got. Appreciate any help.
When you have really large queries like this, it can often be helpful to break them down individually, starting from the ground up and patching them together.
I started by just getting the count of each ucs_mobile row for each projetos_mobile value. You can do that by joining the two tables on the related row, and using COUNT(DISTINCT um.id) to get the number of rows. There are other ways to do it, but this particular method will scale better for the rest of your query:
SELECT pm.id, COALESCE(COUNT(DISTINCT um.id), 0) AS qty_uc
FROM projetos_mobile pm
LEFT JOIN ucs_mobile um ON um.data_hora_importacao = '2015-05-15 17:21:02' AND um.projeto = pm.id_mobile
GROUP BY pm.id;
The COALESCE function will be used to fill 0 counts. As long as you remember to use the DISTINCT keyword, and group by the proper id, you can just add in the child rows like so:
SELECT
pm.id,
COALESCE(COUNT(DISTINCT um.id), 0) AS qty_uc,
COALESCE(COUNT(DISTINCT am.id), 0) AS qty_am,
COALESCE(COUNT(DISTINCT sim.id), 0) AS qty_sim
FROM projetos_mobile pm
LEFT JOIN ucs_mobile um ON um.data_hora_importacao = '2015-05-15 17:21:02' AND um.projeto = pm.id_mobile
LEFT JOIN ambientes_mobile am ON am.data_hora_importacao = um.data_hora_importacao AND am.uc = um.id_uc_mobile
LEFT JOIN secoes_iluminacao_mobile sim ON sim.data_hora_importacao = am.data_hora_importacao AND sim.ambiente = am.id_ambiente_mobile
GROUP BY pm.id;
Here is an SQL Fiddle example. NOTE I changed your sample data slightly to ensure my query was working as expected.
Also, a side note. I noticed as you went along that you kept using the same date in your WHERE clauses, so I just joined each table on the date as well, and made sure that in my very first join I looked for the date specified, which in turn will carry its way over to the other tables.
I have a table structure with three tables: profiles, profile_subrubriek and rubrieken. I query the data with the following query:
SELECT profiles.hoofdrubriek, profiles.plaats
, profiles.bedrijfsnaam, profiles.gemeente, profiles.bedrijfsslogan
, profiles.straatnaam, profiles.huisnummer, profiles.postcode
, profiles.telefoonnummer, profiles.fax, profiles.email
, profiles.website, profiles.bedrijfslogo
FROM profiles INNER JOIN profile_subrubriek ON profiles.ID=profile_subrubriek.profile_id
INNER JOIN rubrieken ON profile_subrubriek.subrubriek_id=rubrieken.ID
where (
rubrieken.rubriek = 'Aannemersbedrijven'
OR
profiles.hoofdrubriek = 'Aannemersbedrijven')
AND profiles.gemeente = 'Dongen'
The result, 0 rows. That is not correct. If I take out the Inner Join and only incorporate the 'hoofdrubriek' column in the WHERE clausule I get about 25 rows as a result, that is correct. So this query (modified version of the above) does actually work:
SELECT profiles.hoofdrubriek, profiles.plaats, profiles.bedrijfsnaam
, profiles.gemeente, profiles.bedrijfsslogan, profiles.straatnaam
, profiles.huisnummer, profiles.postcode, profiles.telefoonnummer
, profiles.fax, profiles.email, profiles.website, profiles.bedrijfslogo
FROM profiles where (profiles.hoofdrubriek = 'Aannemersbedrijven')
AND profiles.gemeente = 'Dongen'
What am I doing wrong?
Thanks!
Probably the joined tables don't contain referenced values. Try LEFT JOIN instead of INNER JOIN.
Start troubleshooting with this query.
select count(*) records
FROM profiles INNER JOIN profile_subrubriek ON profiles.ID=profile_subrubriek.profile_id
If records is greater than 1, add this line and run it again:
INNER JOIN rubrieken ON profile_subrubriek.subrubriek_id=rubrieken.ID
Keep adding bits of your original query, one by one, until records is zero. The last thing you added will be the reason.
I have two tables and joined them to one different table
1 table named 'rec_dept'
id_dept
id_divisi
nama_dept
2 table named 'rec_divisi'
id_divisi
nama_div
3 joined table named 'rec_divdep'
id_divdep
id_divisi
id_dept
How to get nama_dept where in the same id_divisi?
Maybe you're looking for this:
SELECT `nama_dept` FROM `rec_dept` WHERE `id_divisi` IN (SELECT `id_divisi` FROM `rec_divdep`);
Hope that helps
you can do a SELECT query with a LEFT JOIN function to get data
SELECT a.`nama_dept` FROM `rec_dept` a
LEFT JOIN `rec_divisi` b
ON a.`id_divisi` = b.`id_divisi`
ORDER BY a.`id_divisi` ASC
SELECT documentation
LEFT JOIN documentation
select a.id_dept, a.id_divisi, a.nama_dept, b.id_divisi, b.nama_div, c.id_divdep, c.id_divisi from rec_divdep as c left join rec_divisi as b on (c.id_divisi = b.id_divisi) left join rec_dept as a on (c.id_divisi = a.id_divisi)
what database do you use. I code mine as mysql, basically I condition the three tables that has same id_divisi. I did not test it but I am pretty sure of the logic based on what I understand.
Still returns the same results! Got rid of divs. Now the query is:
SELECT w.windate,
w.wintime,
w.field,
w.htname,
w.vtname,
w.plateumpire,
w.fieldumpire1,
w.fieldumpire2,
w.fieldumpire3,
p.pteamname,
p.teamcoach
FROM playerteams AS p
INNER JOIN sportsdb_wins AS w ON p.pteamname IN (w.htname,w.vtname)
WHERE p.teamcoach = '$coachid'
AND p.forteam = '$teamid'
but no joy!
I am trying to display a list of teams that all have the same p.teamcoach. The playerteams table contains each team and has teamcoach set to that coach. sportsdb_wins contains a list of scheduled games that I want to display for a given coach.
How are you associating team coaches to teams. I would suggest you have a table for coaches and foreign key this to the playerteams table. That way your coaches are only entered once. Something like...
SELECT w.windate,
w.wintime,
w.field,
w.htname,
w.vtname,
w.plateumpire,
p.pteamname,
pc.coach_name
FROM player_coaches AS pc
INNER JOIN playerteams AS p
ON p.coachId = pc.coachId
INNER JOIN sportsdb_wins AS w
ON p.pteamname IN (w.htname, w.vtname)
WHERE p.coachId = '$coachId'
AND p.forteam = '$teamId'