I am trying to append 'lookup data' to a main record text/description field so it looks something like this:
This is the Description Text
LookUpName1:
LookupValue1
LookupValueN
This worked fine with Inner Join like so
Select J.id, Concat('<b>LookUpName</b>:<br>',group_concat(F.LookUpValue SEPARATOR '<br>'))
from MainTable J Inner Join
LookUpTable L Inner Join
LookUpValuesTable F
On J.ID = L.JobID and F.ID = L.FilterID
Group by J.ID
However my goal is to add append multiple Lookup Tables and if I add them to this as Inner Joins I naturally just get those record where both/all the LookupTables have records.
On the other hand when I tried Join or Left Join I got an error on the Group by J.ID.
My goal is to append any of the existing Lookup Table values to all of the Description. Right now all I can achieve is returning appended descriptions which have ALL of the Lookup table values.
Your query would work if the on clauses were in the "right" place:
select J.id,
Concat('<b>LookUpName</b>:<br>', group_concat(F.LookUpValue separator '<br>'))
from MainTable J left join
LookUpTable L
on J.ID = L.JobID left join
LookUpValuesTable F
on F.ID = L.FilterID
group by J.ID;
The problem with your query is a MySQL (mis)feature. The on clause is optional for an inner join. Don't ask me why the MySQL designers thought inner join and cross join should be syntactically equivalent. Every other database requires an on clause for an inner join. It is easy enough to express a cross join using on 1=1.
However, the on clause is required for the left join, so when you switch to a left join, the compiler has a problem with the unorthodox syntax. The real problem is a missing on clause; this just happens to show up as "I wasn't expecting a group by yet." Using more traditional syntax with each join followed by an on should fix the problem.
Related
I have this query:
SELECT
GROUP_CONCAT(DISTINCT
`persons`.`name`,
'[START_Name_END]',
`persons`.`id`,
'[START_Id_END]',
`persons`.`isteacher`,
'[START_IsTeacher_END]'
SEPARATOR '[START_ROWSEPERATOR_END]') AS persons_values,
`locations`.`name` AS locations_name,
`locations`.`id` AS locations_id
FROM `locations`
INNER JOIN `locations_persons` ON `locations_persons`.`location_id` = `locations`.`id`
INNER JOIN `persons` ON `persons`.`id` = `locations_persons`.`person_id`
GROUP BY `locations`.`id`
ORDER BY `locations`.`id`
The reason why I use GROUP_CONCAT is to get all rows from persons table, that have reference in the association table, in the same column
I use [START_Name_END], [START_Id_END] to split the result later in my code and [START_ROWSEPERATOR_END] to determine if it's same row or a new one.
Everything works just fine so far.
The thing is if any row in locations table has no reference to any row in persons table, I'm NOT getting that row in the results!
I beleive that the problem is in JOIN, what should I use to fetch all rows regardless if that row has reference in the association table or not?
Any help would be greatly appreciated!
Try using:
LEFT OUTER JOIN `locations_persons` ...
-- Edit
Sorry, I'm new at answering these StackOverflow things and didn't give this the attention that it deserves before responding.
Your table structure is a classic many-to-many join, so if there is no person for a given location, then there would only be location data in the locations table. As such, you would need to have a LEFT OUTER JOIN for both the join on locations_persons AND the join from locations_persons to persons.
If you're still having troubles I'll create a quick MySQL database and test things out.. I'll do that from now on, but thought I should reply more fully now because of my bad partial answer earlier.
--Edit2
Regarding expecting issues: When you left outer join, any join that fails (i.e. there's rows on the left side, but no match on the right side) will have the tables from the right returning all null values. In this case, you would want your query to properly handle all fields in locations_persons and persons returning null values.
If GROUP_CONCAT doesn't deal with this well (I'm not familiar with it), you might need to wrap these persons.* fields in an IFNULL, if you're having problems:
SELECT
GROUP_CONCAT(
DISTINCT `persons`.`name`,
'[START_Name_END]',
IFNULL(`persons`.`id`, ''),
'[START_Id_END]',
IFNULL(`persons`.`isteacher`, ''),
'[START_IsTeacher_END]' SEPARATOR '[START_ROWSEPERATOR_END]'
) AS persons_values,
`locations`.`name` AS locations_name,
`locations`.`id` AS locations_id
FROM
`locations`
LEFT OUTER JOIN `locations_persons` ON
`locations_persons`.`location_id` = `locations`.`id`
LEFT OUTER JOIN `persons` ON
`persons`.`id` = `locations_persons`.`person_id`
GROUP BY
`locations`.`id`
ORDER BY
`locations`.`id`
I am getting issues with the below SQL query, unable to fetch the desired result
SELECT
C.Department__c
,C.Email
,R.AcctID__c
,C.ContactID__c
,R.TransactionDueDate
,R.PubNbr__c
FROM RenewalNotificationProgramDE R
LEFT JOIN ContactNewDE C
ON R.AcctID__c = C.AcctID__c
The idea is to join all the AccountID(AcctID__c) in RenewalNotificationProgramDE table to the corresponding contacts in ContactNewDE table. AccountID is the foreign key in the ContactNewDE table. I am usig Innerjoin in my query as I want all AccountID to map with their corresponding contacts in ContactNewDE.
Just replace LEFT JOIN by INNER JOIN to get all AccountID with their corresponding contacts :-
Use below query :-
SELECT
C.Department__c
,C.Email
,R.AcctID__c
,C.ContactID__c
,R.TransactionDueDate
,R.PubNbr__c
FROM RenewalNotificationProgramDE R
INNER JOIN ContactNewDE C
ON R.AcctID__c = C.AcctID__c
You have used LEFT JOIN in your query, which you need to change it to INNER JOIN. I think you would better to notice the below notes about differences between left and inner joins:
INNER JOIN: Returns all rows when there is at least one match in BOTH
tables
LEFT JOIN: Return all rows from the left table, and the
matched rows from the right table
I have two tables.
Table A:
root_id, root_text
Table B:
word_id , word_text,root_text
Now Some of the records of Table B has root_texts which might not exist in Table A.
So for that I am trying to use left join.
select *
from A a , B b
where a.root_text=+b.root_text
I only get the records which has matching root_text.
If I use the new way
Select
*
from
A left join B on a.root_text= b.root_text
I get so many extra records. I am Using MySQL 5.6.1.7
UPDATE :
http://sqlfiddle.com/#!9/7b32a/2
Query I am running
select * from word_detail w left join roots r
on r.root_text =w.root
and w.surah_no=1
and w.verse_no=1
and w.word_no=1
What I am doing wrong ?
As in result you see so many records which are not needed. The filter verse_no , word_no not working.
Update
The issue was after the left join we have to use where
select * from word_detail w left join roots r
on r.root_text =w.root
where w.surah_no=1
and w.verse_no=1
and w.word_no=1
If you want all records from TableB that are not present in table A you should use this:
Select *
from
B left join A
on a.root_text= b.root_text
where
a.root_text is null
or if you want the opposite - all records from tableA that are not present on tableB:
Select *
from
A left join B
on a.root_text= b.root_text
where
b.root_text is null
btw, this is not a left join on MySQL:
select * from A a , B b where a.root_text=+b.root_text
but will result as a simple INNER JOIN
The += operator is not standard SQL, but specific to the Oracle RDBMS, so it will not work as expected on MySQL.
The LEFT JOIN syntax is correct, the "many extra records" stem from the data in your tables. You might want to use some sort of WHERE as a filter or an aggregate to group the result set to make it more managable.
Your first example is an inner join which explains why you are not getting as many results as when you are left joining. Left joining can also be thought of as a left outer join.
how to convert this left outer join query to subset query
select
j.*, concat(d.Name, ', ', d.Gelar) as DSN,
prg.Nama_Indonesia as PRG,
kl.Kelas as kls,
kl.Sesi as ssi
from
jadwal j left outer join
dosen d on j.IDDosen=d.ID left outer join
kelas kl on j.Kelas=kl.ID left outer join
program prg on j.Program=prg.Kode left outer join
jabatanorganisasi jo on d.JabatanOrganisasi=jo.Kode left outer join
tahun t on j.tahun=t.id
order by
d.Name, prg.Nama_Indonesia, kl.Sesi, kl.Kelas;
please help
give me axample
For the first query you will be having rows, since all of the joins are LEFT JOIN, so atleast all entries from table jadwal will be there in output.
But on the other query you are doing selection using conditions(works like INNER JOIN), if the condition not satisfies there wont be any result-set.Thats why you are not getting any outputs.
There is no data with these conditions.Please check data
where
j.IDDosen=d.ID and
j.kelas=kl.ID and
j.program=prg.kode and
j.tahun=t.id AND
d.JabatanOrganisasi=jo.kode
Hope this helps
In the first query, you are using left joins (which means if there's no match between from table and the joining tables it would retrieve all the results from the from table), and in the second query you are using inner joins.
You can take a look on this What is the difference between "INNER JOIN" and "OUTER JOIN"?
I have 3 tables to select from. 2 of them are always necessary (tbl_notes, tbl_clients) while the 3rd is optional (tbl_notes_categories).
I've always used a LEFT JOIN in my queries with questionable correlating records to the primary table.
But I'm not getting any results with the query below.
Would someone point out how I'm using the LEFT JOIN incorrectly?
SELECT n.*, c.clientname, nc.notecategoryname
FROM tbl_notes n, tbl_clients c
LEFT JOIN tbl_notes_categories nc ON n.categoryid = nc.categoryid
WHERE n.clientid = c.clientid
AND c.clientid = 12345
ORDER BY n.dateinserted DESC
In fact, I'm getting a sql error.
#1054 - Unknown column 'n.categoryid' in 'on clause'
categoryid certainly does exist in tbl_notes
I probably need to brush up on how JOINS really work. I'm guessing I cannot have a LEFT JOIN with 2 database tables before it?
On a side note, I can foresee times when there will be multiple required tables, with several optional tables. (in this case tbl_notes_categories is optional)
Assuming the column categoryid exists in the tbl_notes table...
Try rewriting the query to use the JOIN syntax, rather than using the old-school comma as the join operator. (If the problem isn't a misnamed column, I suspect the problem is in mixing the two types of syntax... but this is just a suspicion, I have no reason to test mixing old-style comma joins with JOIN keywords.)
I'd write the statement like this:
SELECT n.*, c.clientname, nc.notecategoryname
FROM tbl_notes n
JOIN tbl_clients c
ON n.clientid = c.clientid
LEFT
JOIN tbl_notes_categories nc
ON nc.categoryid = n.categoryid
WHERE c.clientid = 12345
ORDER BY n.dateinserted DESC
(Actually, I would specify the individual columns to return from n, rather than using n.*, but that's just a style preference, not a SQL syntax requirement.)