Following is my query:
Select Count(*)
from Table1 s
left join Table2 d
ON s.subjectid = d.subjectid
and s.PROJECTID = d.projectid
and s.SITEName = d.SITENAME
left join Table3 dev
on s.subjectid = dev.subjectid
and s.projectid = dev.projectid
and s.siteid = dev.siteid
Where s.isprod =1
and d.isprod =1
and dev.isprod = 1
and s.projectid =107
-- Output 301 ROWS
This query returns 301 rows. However, if I don't use Table3 then the join returns 2203 rows, as shown in the query below:
Select Count(*)
from Table1 s
left join Table2 d
ON s.subjectid = d.subjectid
and s.PROJECTID = d.projectid
and s.SITEName = d.SITENAME
Where s.isprod =1
and d.isprod =1
and s.projectid =107
-- OutPut 2203 ROWS
By my understanding of left join, all the rows from the left table should remain even if they don't match with the right table. However in this case, the number of rows is reduced from 2203 in query 2 to 301 in query 1. How is that possible?
Please suggest what could be going wrong here. For more clarification:
Table1 with the same where conditions as above has 1300 rows
Table2 with the same where conditions as above has 2203 rows
Table3 with the same where conditions as above has 129 rows
When you have conditions in your where clause that put non-null constraints on the records from the table you have outer joined, you effectively destroy the effect of the outer join, and make it act as an inner join
The solution is to move such constraints into the on clause of the outer join:
Select Count(*)
from Table1 s
left join Table2 d
ON s.subjectid = d.subjectid
and s.PROJECTID = d.projectid
and s.SITEName = d.SITENAME
and d.isprod =1
left join Table3 dev
on s.subjectid = dev.subjectid
and s.projectid = dev.projectid
and s.siteid = dev.siteid
and dev.isprod = 1
Where s.isprod =1
and s.projectid =107
The first SQL has additional "where" clause of "and dev.isprod = 1". Most likely this is reducing the number of rows returned.
Related
I have a large query which combines a lot of tables. I don't want to make this question to complicate so I will try to ask it easy:
suppose I have 3 columns:
table1_device_id, table2_device_id, table3_device_id
I know want to achieve this:
Do a left join on table1_device_id, if that column is null, do a left join on table2_device_id,.. (same for table 3..)
I have following example for 1 table now:
left join query_505727 as inside_weather_data on y.datetime_weather = inside_weather_data.time AND (a.monitor_id is null or a.monitor_id = inside_weather_data.device_id)
but how to do that for multiple?
my query:
select y.datetime_weather, a.site_name as site_name,a.name as house_name, a.name1 as floor_name,a.airspace_name as room_name, a.registration,a.monitor_id, device_color_table.device_id as device_color_device_id, inside_weather_data.device_id as weather_device_id, rdi_data.device_id as rdi_device_id, a.monitor_code as monitor_code, a.alarm_type,a.created_at_date as alarm_date,device_color_table.colors as LED_color_status, rdi_data.value as RDI, ROUND(inside_weather_data.min_inside_temp, 2) as min_inside_temp, ROUND(inside_weather_data.max_inside_temp, 2) as max_inside_temp, y.max_temp as max_outside_temp, y.min_temp as min_outside_temp, y.average_temp as avg_temp, a.alarm_type, a.priority, a.translation_code,a.created_at
from query_505641 as y
left join query_505127 as a on a.created_at_date = y.datetime_weather
left join query_505241 as device_color_table on device_color_table.datetime = y.datetime_weather AND device_color_table.device_id = a.monitor_id
left join query_506556 as rdi_data on rdi_data.time = y.datetime_weather and rdi_data.device_id = a.monitor_id AND device_color_table.device_id is null
left join query_505727 as inside_weather_data on y.datetime_weather = inside_weather_data.time AND inside_weather_data.device_id = a.monitor_id AND coalesce(device_color_table.device_id, rdi_data.device_id) is null
If the table that you want to join to these 3 tables is table then use these LEFT joins:
....
from table t
left join table1 t1 on t1.table1_device_id = t.device_id
left join table2 t2 on t2.table2_device_id = t.device_id and t1.table1_device_id is null
left join table3 t3 on t3.table3_device_id = t.device_id and coalesce(t1.table1_device_id, t2.table2_device_id) is null
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
I need any help getting data from three tables.
This is my setup:
TableA with two columns: id, name
TableB with three columns: id_a, id_c1, id_c2
TableC with two columns: id, name
I want as result the following table:
TableA.name,TableC.name,TableC.name
where the TableC.name(s) are expansion of id_c1, id_c2 of TableB.
Any idea?
Very thanks
You need to join the 3 tables like this:
select a.name, c1.name, c2.name
from tablea a inner join tableb b
on b.id_a = a.id
inner join tablec c1
on c1.id = b.id_c1
inner join tablec c2
on c2.id = b.id_c2
Maybe instead of inner joins you need left joins, but I can't tell for sure.
I have some data about shops that looks something like:
where the unimportant data is omitted.
I have an existing SQLite query:
select s.COMSERNO, s.COMNAME, COMALTNAME, s.COMCODE, s.COMADDR, s.COMPCODE, s.COMCITY, x.lastVisit, y.memoText, l.COMCALL
from TCOMPANY s
left outer join ( select COMSERNO, max(CALEDATE || CALESTART) as lastVisit from TCALENTR where SALMSERN='000000000000019' and (CALEDATE || CALESTART) < strftime('%Y%m%d%H%M', 'now', 'localtime') group by COMSERNO) x on (x.COMSERNO=s.COMSERNO)
left outer join ( select MEMOSERN1 as comSerno, max(MEMOTEXT) as memoText from TMEMO where MEMOTYPE='0' and 0<length(MEMOTEXT) and MEMOSERN2 in ('Notes')group by MEMOSERN1) y on (y.comSerno=s.COMSERNO)
left outer join LSALCOM l on l.COMSERNO=s.COMSERNO
and SALMSERN='000000000000019'
order by s.COMNAME, s.COMSERNO
The above returns 174 rows.
I want to show the 'Chain' for a shop, if it has one, so the data should look something like this:
I have another table, LCOMCOM and for each COMSERNO in my original result set (each shop) I need to determine if this shop is part of a chain and if it is, display that chain.
I join LCOMCOM on COMSERN2, and if the column LCOMATR1 has the value 'Chain' then it means the store COMSERN2 is a chain. I then take COMSERN1 from LCOMCOM and use the original table, TCOMPANY to look up and show the Chain name. Here is my code
case when z.lcomatr1 = 'Chain' then (select p.COMNAME from TCOMPANY p inner join LCOMCOM q on (p.COMSERNO=q.COMSERN2) where q.COMSERN1 = z.comsern1) else '' end as Chain
Here is the LCOMCOM join:
inner join LCOMCOM z on (s.COMSERNO=z.COMSERN2)
I tried adding the above two pieces into my query but it doesn't do what I expected:
select s.COMSERNO, s.COMNAME, COMALTNAME, s.COMCODE, s.COMADDR, s.COMPCODE, s.COMCITY, x.lastVisit, y.memoText, l.COMCALL,
case when z.lcomatr1 = 'Chain' then (select p.COMNAME from TCOMPANY p inner join LCOMCOM q on (p.COMSERNO=q.COMSERN2) where q.COMSERN1 = z.comsern1) else '' end as Chain
from TCOMPANY s
left outer join ( select COMSERNO, max(CALEDATE || CALESTART) as lastVisit from TCALENTR where SALMSERN='000000000000019' and (CALEDATE || CALESTART) < strftime('%Y%m%d%H%M', 'now', 'localtime') group by COMSERNO) x on (x.COMSERNO=s.COMSERNO)
left outer join ( select MEMOSERN1 as comSerno, max(MEMOTEXT) as memoText from TMEMO where MEMOTYPE='0' and 0<length(MEMOTEXT) and MEMOSERN2 in ('Notes')group by MEMOSERN1) y on (y.comSerno=s.COMSERNO)
left outer join LSALCOM l on l.COMSERNO=s.COMSERNO
inner join LCOMCOM z on (s.COMSERNO=z.COMSERN2)
and SALMSERN='000000000000019'
order by s.COMNAME, s.COMSERNO
The above returns 548 rows, not 174. Some shops are now in 4 rows, like so:
And some shops are now in 2 rows, like so:
Adding DISTINCT after the initial SELECT reduces the row count to 348 and it now looks like all the Chain stores are in 2 rows.
I'm not sure what's going on here but presumably referring to TCOMPANY twice in both the SELECTs is wrong. Can anybody tell me how to get 174 rows, with the chain, if appropriate?
The CASE statement wasn't needed and the INNER JOIN was moved into the bracketed SELECT:
select DISTINCT s.COMSERNO, s.COMNAME, COMALTNAME, s.COMCODE, s.COMADDR, s.COMPCODE, s.COMCITY, x.lastVisit, y.memoText, l.COMCALL,
(select p.comname from LCOMCOM q inner join TCOMPANY p on (p.COMSERNO=q.COMSERN1) where q.COMSERN2 = s.comserno and q.lcomatr1 = 'Chain') as Chain
from TCOMPANY s
left outer join ( select COMSERNO, max(CALEDATE || CALESTART) as lastVisit from TCALENTR where SALMSERN='000000000000019' and (CALEDATE || CALESTART) < strftime('%Y%m%d%H%M', 'now', 'localtime') group by COMSERNO) x on (x.COMSERNO=s.COMSERNO)
left outer join ( select MEMOSERN1 as comSerno, max(MEMOTEXT) as memoText from TMEMO where MEMOTYPE='0' and 0<length(MEMOTEXT) and MEMOSERN2 in ('Notes')group by MEMOSERN1) y on (y.comSerno=s.COMSERNO)
left outer join LSALCOM l on l.COMSERNO=s.COMSERNO
and SALMSERN='000000000000019'
order by s.COMNAME, s.COMSERNO
I need to compare data of the same table who do this.
At example, compare A,10 with B,10 when 10 is a repeat value.
You can do this using the cross-product operator, in SQL this would be done as
SELECT T1.colA, T2.colA, (T1.colA < T2.colA) as colA_comp
FROM TableName T1, TableName T2
WHERE T1.colB = T2.colB
What this does is take the cross-product of the table TableName with itself (renamed as T1 and T2), and the WHERE clause filters out those records that agree on colB (the repeated value 10, in your example).
If you compare with the same table then you may use left Join
SELECT t1.cola,t1.colb,t2.cola,...
from tableA t1
LEFT JOIN tableA t2 on t2.cola = t1.cola
WHERE t1.cola = 10
I hope it might be work!