Full Outer Join in sqlite on 4 tables - sqlite

I need to join 4 tables based on a common primary key. If sqlite implemented full outer joins it might look something like this (with optimization not taken into account).
SELECT S.pair, C.ball, P.bluejeans, B.checkered
FROM Socks S
FULL OUTER JOIN Caps C
FULL OUTER JOIN Pants P
FULL OUTER JOIN Boxers B
WHERE S.color = C.color AND S.color = P.color AND S.color = B.color;
I've looked long and hard and the best I found was this 2 table sqlite full join implemented with left joins and union alls:
SELECT employee.*, department.*
FROM employee LEFT JOIN department
ON employee.DepartmentID = department.DepartmentID
UNION ALL SELECT employee.*, department.*
FROM department LEFT JOIN employee
ON employee.DepartmentID = department.DepartmentID
WHERE employee.DepartmentID IS NULL;
I'm trying to modify this to work for more than 2 tables but I'm new to SQL and I'm not getting too far. Is it possible to get this result in a reasonable amount of time?
I think I have a correct implementation for 3 tables (it might not be correct) but I still can't seem to get it for 4. Here's what I have for 3:
SELECT S.pair, C.ball, P.bluejeans
FROM Socks S LEFT JOIN Caps C LEFT JOIN Pants P
ON C.color = S.color AND P.color = S.color
UNION ALL
SELECT S.pair, C.ball, P.bluejeans
FROM Socks S LEFT JOIN Caps C LEFT JOIN Pants P
ON S.color = C.color AND S.color = P.color
WHERE S.color IS NULL;
Any help is much appreciated

The general construction for a full outer join between two tables A and B in SQLite indeed is:
SELECT ... FROM A LEFT JOIN B ON ...
UNION ALL
SELECT ... FROM B LEFT JOIN A ON ... WHERE A.key IS NULL
Now create a view SocksCaps for the full outer join between Socks and Caps:
CREATE VIEW SocksCaps AS
SELECT ... FROM Socks LEFT JOIN Caps ON ...
UNION ALL
SELECT ... FROM Caps LEFT JOIN Socks ON ... WHERE Socks.color IS NULL
Do the same for Pants and Boxers.
Then treat these views just like tables and do a full outer join with the same construction:
SELECT ... FROM SocksCaps LEFT JOIN PantsBoxers ON ...
UNION ALL
SELECT ... FROM PantsBoxers LEFT JOIN SocksCaps ON ... WHERE SocksCaps.color IS NULL

Related

SQL wrong COUNT after two NATURAL JOINs

How many movies in the database were produced by Pixar Animation Studios?
Options:
16
14
18
20
My incorrect solution
SELECT COUNT(movie_id)
FROM productioncompanies
NATURAL JOIN movies
NATURAL JOIN productioncompanies
WHERE production_company_name = "Pixar Animation Studios"
COUNT(movie_id)
4803
You should join productioncompanies to productioncompanymap.
The table movies is not needed because the details of the movies are irrelevant:
SELECT COUNT(*)
FROM productioncompanymap m NATURAL JOIN productioncompanies c
WHERE c.production_company_name = 'Pixar Animation Studios';
or, with an INNER join:
SELECT COUNT(*)
FROM productioncompanymap m INNER JOIN productioncompanies c
ON c.production_company_id = m.production_company_id
WHERE c.production_company_name = 'Pixar Animation Studios';
or, with a correlated subquery:
SELECT COUNT(*)
FROM productioncompanymap
WHERE production_company_id = (
SELECT production_company_id
FROM productioncompanies
WHERE production_company_name = 'Pixar Animation Studios'
);

sqlite query to get instances were no items returned on join

I am querying the static backend db for a game I play (trying to keep up on my coding), and I am having an issue getting the full results that I want.
So the query that I have so far is:
select ms.security, mc.constellationName, mr.regionName, ms.solarSystemName, count(it.typename) as NumberOfBelts
from mapSolarSystems as ms
join mapConstellations as mc on ms.constellationID == mc.constellationID
join mapRegions as mr on ms.regionID == mr.regionID
join invItems as ii on ii.locationID = ms.solarSystemID
join invTypes as it on it.typeID == ii.typeID
where it.groupID = 9
group by solarSystemName
the problem comes when there are no rows where it.groupID == 9. What I need is for the count to return 0 and I can't for the life of me figure out how to get this to work.
I tried doing left outer join on the final join statement, but no joy.
Change the last join to a left join and set the condition in the on clause istead of the where clause:
select ms.security, mc.constellationName, mr.regionName, ms.solarSystemName, count(it.typename) as NumberOfBelts
from mapSolarSystems as ms
join mapConstellations as mc on ms.constellationID = mc.constellationID
join mapRegions as mr on ms.regionID = mr.regionID
join invItems as ii on ii.locationID = ms.solarSystemID
left join invTypes as it on it.typeID = ii.typeID and it.groupID = 9
group by solarSystemName

Doctrine DQL with multiple joined tables

i have entities **target,citytarget,city,cityplace,place
citytarget & cityplace are pivot tables that connect t&c and c&p
i need the places for given city name and a target id
i tried the following DQL:
SELECT t,c,p FROM MulticatorBundle:Target t
join t.cities ct
join ct.cities c
join c.places cp
join cp.places p
where c.name like '%Stahmeln%'
But i receive:
result: The parent object of entity result with alias 'c' was not found. The parent alias is 'ct'.
i dont know any further....
a plain SQL could be:
select * from target
left join citytarget on citytarget.target_id = target.id
left join city on citytarget.city_id = city.id
left join cityplace on cityplace.city_id = city.id
left join place on cityplace.id = place.id
where target.id = 1
and city.name like \'%Stahmeln%\'
Adrian
You always need your parent entity in your select. In this case:
SELECT ct, c, cp, t, p
is needed
You need to do
SELECT t,ct, c, cp ,p FROM MulticatorBundle:Target t
join t.cities ct
join ct.cities c
join c.places cp
join cp.places p
where c.name like '%Stahmeln%'
Hope this help you

Join the result of two tables join with a third table?

I have three tables
POS_ITEM ( have 4 columns [ITEM_col1,ITEM_col2,ITEM_col3,ITEM_col4])
POS_MAP ( have 3 columns [MAP_col1, MAP_col2,MAP_col3])
POS_DIS ( have 5 columns [DIS_col1,DIS_col2.DIS_col3,DIS_col4,DIS_col5])
I have to perform a left outer join from POS_ITEM to POS_MAP, which I've been able to do. But now I have to join this result with a third table, POS_DIS.
I tried this
select b.MAP_col2,a.ITEM_col1,a.ITEM_col2,a.ITEM_col3
FROM POS_ITEM as b
left outer JOIN POS_MAP as a on a.ITEM_col1=b.MAP_col2 as h
left Outer JOIN POS_DIS as d on d.DIS_col1=h.MAP_col2 ;
but it isn't working.
I've tried this
(select b.MAP_col2,a.ITEM_col1,a.ITEM_col2,a.ITEM_col3
FROM POS_ITEM as b
left outer JOIN POS_MAP as a on a.ITEM_col1=b.MAP_col2) as h
left Outer JOIN POS_DIS as d on d.DIS_col1=h.MAP_col2 ;
But this fails saying that "(" is not a valid character.
Is this not possible with Sqlite? If so, what am I doing wrong? If not, what are my alternatives?
finally cracked it...the result will be appending...no need to add braces
select b.MAP_col2,a.ITEM_col1,a.ITEM_col2,a.ITEM_col3
FROM POS_ITEM as b
left outer JOIN POS_MAP as a on a.ITEM_col1=b.MAP_col2
left Outer JOIN POS_DIS as d on d.DIS_col1=b.MAP_col2 ;

problem with nested inner joins in SQLIte

The sql statement below will not run in SQLite:
select *
from A
left join (B inner join C on B.fkC = C.pk) on A.optionalfkB = B.pk
I get a sqlException "unknown column B.pk"
According to the documentation # http://www.sqlite.org/lang_select.html this should work, and it will work in all other sql implementations. Am I doing something wrong?
It doesn't work because the "outer" query doesn't know what B is.
select *
from A
left join (B inner join C on B.fkC = C.pk) B on A.optionalfkB = B.pk
The (B inner join C on B.fkC = C.pk) is weird without any select, but the specification does say that it is valid.

Resources