I am trying to do a simple LEFT JOIN of a table in couchbase. Here is what I have:
SELECT
a.*,
b.id,
b.name
FROM my_table AS a LEFT JOIN my_table AS b
ON KEYS a.pid
WHERE a.id='abc'
but for some reason the result I get is not including the fields of the table on the right side. Can anyone help me to achieve something similar to what we can do in relational database SQL as below?
SELECT
a.*,
b.id,
b.name
FROM my_table AS a LEFT JOIN my_table AS b
ON a.pid=b.id
WHERE a.id='abc'
thanks!
If nothing matched right side of JOIN projected as MISSING in (NOSQL) JSON vs NULL in SQL (i.e it gives LEFT side document extend right side as MISSING)
SELECT
a.*,
(CASE WHEN b IS MISSING THEN NULL ELSE b.id END) AS id,
(CASE WHEN b IS MISSING THEN NULL ELSE b.name END) AS name
FROM my_table AS a LEFT JOIN my_table AS b
ON KEYS a.pid
WHERE a.id='abc';
If the document b is matched and b.name is MISSING you still get MISSING. If you need null try this.
SELECT
a.*,
(CASE WHEN b.id IS MISSING THEN NULL ELSE b.id END) AS id,
(CASE WHEN b.name IS MISSING THEN NULL ELSE b.name END) AS name
FROM my_table AS a LEFT JOIN my_table AS b
ON KEYS a.pid
WHERE a.id='abc';
SELECT
a.*,
IFMISSING(b.id,NULL) AS id,
IFMISSING(b.name,NULL) AS name
FROM my_table AS a LEFT JOIN my_table AS b
ON KEYS a.pid
WHERE a.id='abc';
Related
I want to combine all the related data using LEFT JOIN clause but if one of tables has no matched record from other table it will not show up. Can you check my queries it seems that there is missing or totally messed up. Here's my query.
SELECT*
FROM
MASTER_TBL
LEFT JOIN
(
SELECT*
FROM
TBLA A
LEFT JOIN
TBLB B
ON
A.ID=B.ID AND A.DESC=B.DESC
LEFT JOIN
TBLC C
ON
B.ID=C.ID AND B.DESC=C.DESC
LEFT JOIN
TBLD D
ON
C.ID=D.ID AND C.DESC=D.DESC
) E
ON
MASTER_TBL.ID=E.ID
The problem is that you are cascading the conditions across joins. For example, here are the join conditions for table d:
C.ID = D.ID AND C.DESC = D.DESC
For this to match, you need to have a matching row in C already.
As your query stands, it looks like you can use the id from the master table to search all the following tables. As for the desc columns, it looks like your best pick is to use that of table a.
So, consider:
select *
from master_tbl m
left join tbla a on a.id = m.id
left join tblb b on b.id = m.id and b.desc = a.desc
left join tblc c on c.id = m.id and c.desc = a.desc
left join tbld d on d.id = m.id and d.desc = a.desc
If all descs are not available in tablea, we could switch to full joins. The logic is more complicated to follow, but that would look like:
select *
from master_tbl m
full join tbla a on a.id = m.id
full join tblb b on b.id = m.id and b.desc = a.desc
full join tblc c on c.id = m.id and c.desc = coalesce(a.desc, b.desc)
full join tbld d on d.id = m.id and d.desc = coalesce(a.desc, b.desc, c.desc)
This approach uses UNION ALL to combine the letter named tables (tbla, tblb, tblc, tbld) into a CTE, common table expression. The combined table is then summarized by id, [desc] and crosstabulated (or pivoted) across the login columns. The pivoted result is then LEFT JOIN'ed to the master_tbl. Something like this.
with
tbl_cte(tbl, id, [login], [desc]) as (
select 'A', * from tbla
union all
select 'B', * from tblb
union all
select 'C', * from tblc
union all
select 'D', * from tblc),
pvt_cte(id, tbla_login, tblb_login, tblc_login, tbld_login, [desc]) as (
select id,
max(case when tbl='A' then [login] else null end) as tbla_login,
max(case when tbl='B' then [login] else null end) as tblb_login,
max(case when tbl='C' then [login] else null end) as tblc_login,
max(case when tbl='D' then [login] else null end) as tbld_login,
[desc]
from tbl_cte
group by id, [desc])
select mt.id, [name], country, [status], pc.tbla_login,
pc.tblb_login, pc.tblc_login, pc.tbld_login, pc.[desc]
from master_tbl mt
left join pvt_cte pc on mt.id=pc.id;
I know this has been asked a lot but I can't seem to get my query working.
I'm trying to get only one row per id in a query looking like this :
SELECT a.id, b.name
FROM table1 a
LEFT JOIN table2 b ON a.key = b.key
WHERE a.Date =
(SELECT MAX(a1.date) from table1 WHERE a1.primarykey = a.primarykey)
GROUP BY a.id, b.name
I do not need to group by b.name but have to since I need to group by id.
Right now, I have multiple occurences for b.name which duplicates a.id where I just want the corresponding b.name for the last date for a.id.
Can anyone point me to the right way to do this ?
Thank you
I guess this condition:
WHERE a1.primarykey = a.primarykey
should be:
WHERE a1.key = a.key
and key is not the primary key of table1, because if you really mean the primary key then there is no point to search for the MAX(date) for the primary key since there is only 1 date for each primary key.
If I'm not wrong then try with row_number():
SELECT t.id, t.name
FROM (
SELECT a.id, b.name,
row_number() over (partition by a.key order by a.date desc) rn
FROM table1 a LEFT JOIN table2 b
ON a.key = b.key
) t
WHERE t.rn = 1
It looks like you would be getting 1 row per id if you would be removing b.name from your group statement.
Not sure why you would need to group on b.name if you group on a.id?
try this:
SELECT a.id, b.name from (
SELECT a1.id,a1.key,
rank() over(partition by a1.key order by a1.date desc) md FROM table1 a1 )a
LEFT JOIN table2 b ON a.key = b.key and a.md=1;
but I don't get -you need group by Id or key, double check it
I need make a decision which table should be use in join statement depend on values in another table
I tried using CASE and COALESCE but can't achieve any success.
TableA has A and B and C and many other columns
TableB has ID and NAME columns
TableC has ID and NAME columns
My select statement is;
Select A.D, A.E, A.F From TableA A
If A.E = 1 then the following join should be used
left outer join TableB B ON A.B = B.ID
and B.NAME should be returned in the select statement
If A.E = 2 then the following join should be used
left outer join TableC C ON A.B = C.ID
and C.NAME should be returned in the select statement
Just add your conditions to the joins, and then use a case statement to pull the correct field to your result set e.g.
select A.D, A.E, A.F
, case when B.[Name] is not null then B.[Name] else C.[Name] end [Name]
from TableA A
left outer join TableB B ON A.B = B.ID and A.E = 1
left outer join TableC C ON A.B = C.ID and A.E = 2
Join tablea with the union of tableb with an extra column with value 1 and tablec with an extra column with value 2 and apply the conditions in the ON clause:
select
a.D, a.E, a.F, u.NAME
from tablea a
left join (
select *, 1 col from tableb
union all
select *, 2 col from tablec
) u on a.B = u.id and a.E = u.col
I have the following tables
Table A
ID "Other Columns"
1
2
3
Table B
ID "Other Columns"
3
4
5
What is the efficient way to return the below result?
Result
ID "Other Columns"
1
2
4
5
A full outer join should work, and only go through each table once. They can be tricky, so test carefully!
SELECT
isnull(A.ID, B.ID) ID
,"Other columns" -- Handle nulls properly!
from TableA A
full outer joing TableB B
on B.ID = A.ID
where not (A.ID is not null
and B.ID is not null)
You want to use left and right join and union them
Select TableA.ID as 'ID','Other Colums'
FROM TableA Left join TableB
ON TableA.ID=TableB.ID
WHERE TableB.ID IS NULL
UNION
Select TableB.ID as 'ID','Other Colums'
FROM TableA Right join TableB
ON TableA.ID=TableB.ID
WHERE TableA.ID IS NULL
You can try like this
SELECT
COALESCE(a.id, b.id),
OtherColumns
FROM #tablea a
FULL JOIN #tableb b
ON a.id = b.id
WHERE a.id IS NULL
OR b.id IS NULL
You can do this with a UNION ALL using a LEFT JOIN to determine if the ID is not in the other table. Keep in mind that the column count and datatypes between the two tables must match up:
Select A.Id, A.OtherColumns
From TableA A
Left Join TableB B On A.Id = B.Id
Where B.Id Is Null
Union All
Select B.Id, B.OtherColumns
From TableB B
Left Join TableA A On A.Id = B.Id
Where A.Id Is Null
Not quite sure what you need with the "Other columns", but you could use EXCEPT:
Select ID from TableA
EXCEPT
Select ID from TableB
If you need Other columns from TableA you could use:
Select ID, OtherColumn1, OtherColumn2 from TableA
where ID not in (select ID from TableB)
(as long as ID cannot be null in TableB)
I broke down each part to be clearer!
select *
into #temp
from
TabA Full outer join TabB
on TabA.ColNameA = TabB.ColNameB
select *
into #temp2
from #temp
where (ColNameA is Null Or ColNameB is null)
select ColNameA from #temp2
where ColNameA Is not null
union
select ColNameB from #temp2
where ColNameB Is not null
I have a properly working query
select A.*, B.*
from A left join B on A.id = B.id and B.country = 'USA'
Now with left join I can put only 1 condition ( A.id = B.id). So I have to put B.country = 'USA' part somewhere else. Is there any workaround? I can use subqueries.
Update: I have to work with a framework (DBIx::Class) where I have defined single condition ( Id matching) in Schema and it is not straightforward to alter that.
You could break B into a subquery and filter there instead of at the join
SELECT A.*, B.*
FROM A
LEFT JOIN (
SELECT *
FROM B
WHERE COUNTRY = 'USA'
) B
ON A.ID = B.ID