Hello i'm learning sql and i have some issues with joins(which i have problems understanding them)
I have this issue
#1066 - Not unique table/alias: 'tbl_respuestas'
what the query supposed to do, is count how many people(general,ignore user) has answer 'x', in 'y' question of 'z' survey
SELECT COUNT(*) FROM tbl_respuestas
INNER JOIN tbl_encuesta_usuario ON tbl_encuesta_usuario.user_id = user.id
INNER JOIN tbl_encuesta ON tbl_encuesta.id = tbl_encuesta_usuario.tbl_encuesta_id
INNER JOIN tbl_encuesta_has_tbl_preguntas ON tbl_encuesta_has_tbl_preguntas.tbl_encuesta_id = tbl_encuesta.id
INNER JOIN tbl_preguntas ON tbl_preguntas.id = tbl_encuesta_has_tbl_preguntas.tbl_preguntas_id
INNER JOIN tbl_preguntas_has_tbl_respuestas ON tbl_preguntas_has_tbl_respuestas.tbl_preguntas_id = tbl_preguntas.id
INNER JOIN tbl_respuestas ON tbl_respuestas.id = tbl_preguntas_has_tbl_respuestas.tbl_respuestas_id
WHERE tbl_respuestas.respuesta = 2
line SELECT COUNT(*) FROM tbl_respuestas
and line INNER JOIN tbl_respuestas
does not makes sense, hence the error.
Unless it is what you want then you need to give then different name/alias like below:
SELECT COUNT(*) FROM tbl_respuestas r
INNER JOIN tbl_respuestas r2
Also as a quick note you can rewrite the entire sql like below.
It is good practice to give your tables a name for shorter referencing and makes the sql look a little cleaner.
Also if both tables you are trying to join has the same column name then you can use the keyword USING instead of having to write that long line tbl_encuesta_usuario.user_id = user.id
Please be sure to put r and r2 in its prope place
SELECT COUNT(*) FROM tbl_respuestas r
INNER JOIN tbl_encuesta_usuario u USING user_id
INNER JOIN tbl_encuesta e ON e.id = u.tbl_encuesta_id
INNER JOIN tbl_encuesta_has_tbl_preguntas hp ON hp.tbl_encuesta_id = e.id
INNER JOIN tbl_preguntas p ON p.id = hp.tbl_preguntas_id
INNER JOIN tbl_preguntas_has_tbl_respuestas hr ON hr.tbl_preguntas_id = p.id
INNER JOIN tbl_respuestas r2 ON r2.id = hr.tbl_respuestas_id
WHERE r.respuesta = 2
I'm working on a project that each orgnizations have barriers, each organization can contain 1 or more barriers, and then I need generate an XML file that show each barrier into the organization .
But executing this sql code:
SELECT organizations.*, barriers.barrierName AS bname, barriers.type AS btype, geographs.name AS geo, rpd.rpdname AS rpdn, rpd.meaning AS rpdmean FROM organizations
left join orgbarriers on orgbarriers.idOrg = organizations.id
left join barriers on orgbarriers.idBarrier = barriers.id
left join orggeographs on organizations.id = orggeographs.idOrg
left join geographs on geographs.id = orggeographs.idGeo
left join orgrpds on orgrpds.idOrg = organizations.id
left join rpd on rpd.id = orgrpds.idRPD
I get repeated rows like this image:
Use the keyword "DISTINCT"
SELECT DISTINCT rest of your query
I'm trying to get data from multiple tales using LEFT OUTER JOIN but I'm getting a fatal error.
Table names, field names, db connection are correct.
$sql = "SELECT shipping_info.shipping_id, service1.service, package1.package_type, countries1.country AS fromCountry, countries2.country AS toCountry, countries3.country AS resiCountry, customer1.name,
FROM shipping_info
LEFT OUTER JOIN service_types AS service1 ON shipping_info.service_type = service_types.serviceType_id
LEFT OUTER JOIN package_types AS package1 ON shipping_info.package_type = package_types.packageType_id
LEFT OUTER JOIN customer_info AS customer1 ON shipping_info.customer_id = customer_info.customer_id
LEFT OUTER JOIN countries AS countries1 ON shipping_info.from_loc = countries1.country_id
LEFT OUTER JOIN countries AS countries2 ON shipping_info.to_loc= countries2.country_id
LEFT OUTER JOIN countries AS countries3 ON shipping_info.to_id = countries3.country_id
ORDER BY shipping_info.order_date DESC";
Fatal error: Call to a member function fetchAll() on a non-object in....
try changing your query to this:
SELECT s1.shipping_id,
s1.service,
p1.package_type,
c1.country fromCountry,
c2.country toCountry,
c3.country resiCountry,
c1.name
FROM shipping_info si
LEFT JOIN service_types s1 ON si.service_type = s1.serviceType_id
LEFT JOIN package_types p1 ON si.package_type = p1.packageType_id
LEFT JOIN customer_info c1 ON si.customer_id = c1.customer_id
LEFT JOIN countries c1 ON si.from_loc = c1.country_id
LEFT JOIN countries c2 ON si.to_loc= c2.country_id
LEFT JOIN countries c3 ON si.to_id = c3.country_id
ORDER BY si.order_date DESC;
you had multiple typos in the query itself with incorrect syntax.. also LEFT OUTER JOIN and LEFT JOIN are exactly the same
Also can you post how you are executing this query? you may have an issue with the actual method for executing it.
I'm not a MySQL expert, but this looks wrong. Consider your first join:
LEFT OUTER JOIN service_types AS service1
ON shipping_info.service_type = service_types.serviceType_id
You give table service_types an alias (a correlation name) of service1, but then don't use it in the ON part of the join. The first thing I would try is either get rid of the correlation name:
LEFT OUTER JOIN service_types
ON shipping_info.service_type = service_types.serviceType_id
...or use it:
LEFT OUTER JOIN service_types AS service1
ON shipping_info.service_type = service1.serviceType_id
Since you're using it in the names of the columns you're actually selecting, I'd go with using it in ON part of the join. Whichever, repeat with package_types and customer_info and then try.
Right off the bat I can see that you have an extra comma just before the FROM clause. This would cause an error and could result in the error you are getting as you would be running fetchAll on a non-object, i.e. the query that wasn't formatted properly.
Your table aliases are pretty long, so you could either shorten them or ditch them altogether and just use the full table name.
SELECT
si.shipping_id,
st.service,
pt.package_type,
c1.country AS fromCountry,
c2.country AS toCountry,
c3.country AS resiCountry,
ci.name
FROM shipping_info si
LEFT JOIN service_types st
ON si.service_type = st.serviceType_id
LEFT JOIN package_types pt
ON si.package_type = pt.packageType_id
LEFT JOIN customer_info ci
ON si.customer_id = ci.customer_id
LEFT JOIN countries c1
ON si.from_loc = c1.country_id
LEFT JOIN countries c2
ON si.to_loc= c2.country_id
LEFT JOIN countries c3
ON si.to_id = c3.country_id
ORDER BY si.order_date DESC;
Also, I've recently moved over to using MySQL Workbench. It's definitely worth checking out. I like it better than PHPMyAdmin. It's a better workflow for me and has cool tools like the reverse engineer tool that will build an ERD for you based on your tables. It's great for testing out your queries before using them in your PHP code.
MySQL Workbench
http://www.mysql.com/products/workbench/
Ok I have 5 tables in my database they are as follows
officelocations_tbl
state_tbl
city_tbl
staff_tbl
titles_tbl
The titles table is only associated with the staff table but the others are all inner joined. I have tried various mysql statements but none are allowing me to bring in the titles_tbl.
here is the latest version of the sql statement I am attempting to use:
SELECT officelocations_tbl.*,city_tbl.*, state_tbl.* , titles_tbl.*,
contact1.firstName AS c1Firstname, contact1.lastName AS c1lastName,
contact1.middleInitial AS c1middleInitial, contact1.suffix AS c1suffix,
contact1.accredations AS c1accredations, contact1.phone AS c1Phone,
contact1.faxNumber AS c1FaxNumber, contact1.mobilePhone AS c1Mobile,
contact1.email AS c1Email, contact1.titleID AS c1Title,
contact2.firstName AS c2Firstname, contact2.lastName AS c2lastName,
contact2.middleInitial AS c2middleInitial, contact2.suffix AS c2suffix,
contact2.accredations AS c2accredations, contact2.phone AS c2Phone,
contact2.faxNumber AS c2FaxNumber, contact2.mobilePhone AS c2Mobile,
contact2.email AS c2Email, contact2.titleID AS c2Title,
partner.firstName AS c3Firstname, partner.lastName AS c3lastName,
partner.middleInitial AS c3middleInitial, partner.suffix AS c3suffix,
partner.accredations AS c3accredations, partner.phone AS c3Phone,
partner.faxNumber AS c3FaxNumber, partner.mobilePhone AS c3Mobile,
partner.email AS c3Email, partner.titleID AS c3Title
FROM officelocations_tbl
JOIN city_tbl ON (officelocations_tbl.cityID = city_tbl.cityID)
INNER JOIN titles_tbl ON titles_tbl.titleID = staff_tbl.titleID
LEFT OUTER JOIN state_tbl ON (officelocations_tbl.stateID = state_tbl.stateID)
LEFT OUTER JOIN staff_tbl contact1 ON (contact1.staffID = officelocations_tbl.contact1)
LEFT OUTER JOIN staff_tbl contact2 ON (contact2.staffID = officelocations_tbl.contact2)
LEFT OUTER JOIN staff_tbl partner ON (partner.staffID = officelocations_tbl.partner)
However this gives me an error [Err] 1054 - Unknown column 'staff_tbl.titleID' in 'on clause'. If I remove both the lines:
INNER JOIN titles_tbl ON titles_tbl.titleID = staff_tbl.titleID
titles_tbl.*,
it works but doesn't pull in the title. I have tried doing it this way as well but then it only pulls in the title once and not for all three contacts.
SELECT
staff_tbl.staffID,
staff_tbl.staffID_C2,
staff_tbl.staffID_P,
staff_tbl.firstName,
staff_tbl.middleInitial,
staff_tbl.lastName,
staff_tbl.suffix,
staff_tbl.accredations,
staff_tbl.email,
staff_tbl.phone,
staff_tbl.mobilePhone,
staff_tbl.officePhone,
staff_tbl.faxNumber,
staff_tbl.address1,
staff_tbl.address2,
staff_tbl.cityID,
staff_tbl.stateID,
staff_tbl.zipCode,
staff_tbl.titleID,
staff_tbl.locationID,
staff_tbl.photoURL,
staff_tbl.vCardURL,
staff_tbl.qRCodeURL,
staff_tbl.resumeURL,
staff_tbl.biography,
staff_tbl.dateCreated,
officelocations_tbl.locationID,
officelocations_tbl.officeName,
officelocations_tbl.address1,
officelocations_tbl.address2,
officelocations_tbl.cityID,
officelocations_tbl.stateID,
officelocations_tbl.zipCode,
officelocations_tbl.officePhone,
officelocations_tbl.contact1,
officelocations_tbl.contact2,
officelocations_tbl.partner,
city_tbl.cityID,
city_tbl.cityName,
state_tbl.stateID,
state_tbl.state_abreviation,
state_tbl.state_name,
titles_tbl.titleID,
titles_tbl.titleName,
contact1.firstName AS c1Firstname, contact1.lastName AS c1lastName,
contact1.middleInitial AS c1middleInitial, contact1.suffix AS c1suffix,
contact1.accredations AS c1accredations, contact1.phone AS c1Phone,
contact1.faxNumber AS c1FaxNumber, contact1.mobilePhone AS c1Mobile,
contact1.email AS c1Email, contact1.titleID AS c1Title,
contact2.firstName AS c2Firstname, contact2.lastName AS c2lastName,
contact2.middleInitial AS c2middleInitial, contact2.suffix AS c2suffix,
contact2.accredations AS c2accredations, contact2.phone AS c2Phone,
contact2.faxNumber AS c2FaxNumber, contact2.mobilePhone AS c2Mobile,
contact2.email AS c2Email, contact2.titleID AS c2Title,
partner.firstName AS c3Firstname, partner.lastName AS c3lastName,
partner.middleInitial AS c3middleInitial, partner.suffix AS c3suffix,
partner.accredations AS c3accredations, partner.phone AS c3Phone,
partner.faxNumber AS c3FaxNumber, partner.mobilePhone AS c3Mobile,
partner.email AS c3Email, partner.titleID AS c3Title
FROM officelocations_tbl
INNER JOIN staff_tbl ON staff_tbl.staffID = officelocations_tbl.contact1
INNER JOIN state_tbl ON state_tbl.stateID = officelocations_tbl.stateID
INNER JOIN titles_tbl ON titles_tbl.titleID = staff_tbl.titleID
INNER JOIN city_tbl ON city_tbl.cityID = officelocations_tbl.cityID
LEFT OUTER JOIN staff_tbl contact1 ON (contact1.staffID = officelocations_tbl.contact1)
LEFT OUTER JOIN staff_tbl contact2 ON (contact2.staffID = officelocations_tbl.contact2)
LEFT OUTER JOIN staff_tbl partner ON (partner.staffID = officelocations_tbl.partner)
This will only pull for the first association of staff_tbl.staffID = officelocations_tbl.contact1. I am stumped as to what to try next. Is there anyone who would know how to get it to pull all 5 tables?
You just need to move your INNER JOIN down lower, e.g. from
INNER JOIN titles_tbl ON titles_tbl.titleID = staff_tbl.titleID
LEFT OUTER JOIN state_tbl ON (officelocations_tbl.stateID = state_tbl.stateID)
to
LEFT OUTER JOIN state_tbl ON (officelocations_tbl.stateID = state_tbl.stateID)
INNER JOIN titles_tbl ON titles_tbl.titleID = staff_tbl.titleID
At the time the parser reaches the INNER JOIN, staff_tbl has not yet been joined, and the parser will not "look ahead" to see if it's joined later. So it immediately bails with a "no such table/field".
Switching the order in which this occurs allows taff_table to be joined in first, and then you can use it in further joins.
I have Doctrine2 DQL query but I want to build it with QueryBuilder, I have noticed that produced DQL is somewhat different from the handcrafted one, and I'm wondering what am I missing here - maybe I'm not aware of something or doing things wrong way?
Ok, some details:
My handcrafted query looks like this:
select count(fi.id)
from Entities\Content\FolderLookup fl
join fl.site fls
join fl.folder flf,
Entities\Content\FolderItem fi
join fi.site fis
join fi.folder fif
join fi.item it
join it.type tp
join it.content ic
where fl.namePath = ?1
and tp.name = ?2
and fls.id = fis.id
and flf.id = fif.id
Now, I'm trying to reproduce it like this with QueryBuilder:
$qb->select("count(fi.id)")->from("Entities\Content\FolderLookup", "fl")->join("fl.site","fls")->join("fl.folder", "flf");
$qb->from("Entities\Content\FolderItem","fi")->join("fi.site","fis")->join("fi.folder","fif");
$qb->join("fi.item","it")->join("it.type","tp")->join("it.content","ic");
$wherePart = $qb->expr()->andx();
$wherePart->add($qb->expr()->eq("fl.namePath","?1"));
$wherePart->add($qb->expr()->eq("tp.name","?2"));
$wherePart->add($qb->expr()->eq("fls.id","fis.id"));
$wherePart->add($qb->expr()->eq("flf.id","fif.id"));
$qb->where($wherePart);
This however is producing this DQL query:
SELECT count(fi.id) FROM Entities\Content\FolderLookup fl,
Entities\Content\FolderItem fi
INNER JOIN fl.site fls
INNER JOIN fl.folder flf
INNER JOIN fi.site fis
INNER JOIN fi.folder fif
INNER JOIN fi.item it
INNER JOIN it.type tp
INNER JOIN it.content ic
WHERE (fl.namePath = ?1)
AND (tp.name = ?2)
AND (fls.id = fis.id)
AND (flf.id = fif.id)
As you can see there is part of this missing comapring to handcrafted one (First line):
fl join fl.site fls join fl.folder flf
I'm not sure why these joins are missing as I am defining them here:
$qb->select("count(fi.id)")->from("Entities\Content\FolderLookup", "fl")->join("fl.site","fls")->join("fl.folder", "flf");
Update:
The fun part starts, when DQL gets translated into SQL - in this case MySQL:
Handcrafted one becomes:
SELECT count(f0_.id) AS sclr0 FROM FolderLookup f1_ INNER JOIN Site s2_ ON f1_.site_id = s2_.id INNER JOIN Folder f3_ ON f1_.folder_id = f3_.id, FolderItem f0_ INNER JOIN Site s4_ ON f0_.site_id = s4_.id INNER JOIN Folder f5_ ON f0_.folder_id = f5_.id INNER JOIN Item i6_ ON f0_.item_id = i6_.id INNER JOIN ItemType i7_ ON i6_.type_id = i7_.id INNER JOIN ItemContent i8_ ON i6_.content_id = i8_.id WHERE f1_.namePath = ? AND i7_.name = ? AND s2_.id = s4_.id AND f3_.id = f5_.id
Where generated one looks like this:
SELECT count(f0_.id) AS sclr0 FROM FolderLookup f1_, FolderItem f0_ INNER JOIN Site s2_ ON f1_.site_id = s2_.id INNER JOIN Folder f3_ ON f1_.folder_id = f3_.id INNER JOIN Site s4_ ON f0_.site_id = s4_.id INNER JOIN Folder f5_ ON f0_.folder_id = f5_.id INNER JOIN Item i6_ ON f0_.item_id = i6_.id INNER JOIN ItemType i7_ ON i6_.type_id = i7_.id INNER JOIN ItemContent i8_ ON i6_.content_id = i8_.id WHERE (f1_.namePath = ?) AND (i7_.name = ?) AND (s2_.id = s4_.id) AND (f3_.id = f5_.id)
And this is invalid statement, as database returns with:
Column not found: 1054 Unknown column 'f1_.site_id' in 'on clause'
Any ideas welcome.
It seems the DQL parser is wrongly positioning the joins to the wrong from.
My initial suggestion is to try to make only 1 FROM item and a subselect.
Also, I'd love if you add the same content you asked here in our bug tracking: http://www.doctrine-project.org/jira/browse/DDC
Thanks a lot!
Guilherme Blanco
Doctirne Core Developer
they are not missing. just reordered
INNER JOIN fl.site fls
INNER JOIN fl.folder flf