I have two table with name LeftTable and RightTable as below
LeftTable
obsid Name Value
1 Ronak A
2 Aakash B
3 Pankti C
4 Sanket D
RightTable
obsid Name Value
1 Jhone F
2 Isabella M
3 Jonathan L
4 javafx p
Now when I Left join in some condition the output will be as below
ResultTable
obsid Name Value obsid Name Value
-------------------------------------------------------------------------
1 Ronak A 1 Jhone F
1 Ronak A 2 Isabella M
1 Ronak A 3 Jonathan L
1 Ronak A 4 javafx p
2 Aakash B 2 Isabella M
2 Aakash B 3 Jonathan L
2 Aakash B 4 javafx p
3 Pankti C 3 Jonathan L
3 Pankti C 4 javafx p
4 Sanket D 4 javafx p
This Left Join is help me to achieve One-To-Many Relationship in my application.
Left join condition is dynamic in my application. so its just an example I shown here. Suppose Left Join condition in above exampple is LeftTable.Obsid <= RightTable.Obsid
Now I want to achieve One-To-One relationship.
One-To-One relationship means when any of righttable record linked once with any lefttable record then that righttble record can not be linked with any other lefttable record.
For above example Output for one to one is as below
obsid Name Value obsid Name Value
1 Ronak A 1 Jhone F
2 Aakash B 2 Isabella M
3 Pankti C 3 Jonathan L
4 Sanket D 4 javafx p
I have achieve this functionality two way:
Using cursor
fetching one by one record using select query
Database tables are dynamic in my application. so while processing on millions of record takes too much time as fetching one by one record and processing on it takes time.
Is there any way to achieve One-To-One relation in single select query??
I want to avoid fetching one by one record and I am using Mysql database
Please help me.
You can achieve the required output which is shown in the example by just using inner join.
select * from LeftTable L inner join RightTable R
on L.obsid=R.obsid
But I if there are duplicate obsid in the left table you can use the below query
select A.obsid,A.Name,A.Value, R.obsid,R.Name,R.Value from(
select *,row_number() over (partition by obsid order by obsid ) as row_num
from LeftTable)A
inner join RightTable R
on A.obsid=R.obsid
where A.row_num=1
Please let me know this is what you expect
Related
I'm doing an inner join on a table like this:
SELECT *
FROM patient p
INNER JOIN
vaccine v
ON
p.vaccine_id = v.id
The condition f.vac_1 = mv.id might not been satisfied in the case where a person have not been vaccinated. In such case, I don't want to ignore the row, but instead of displaying the vaccine name (which is the purpose of the inner join) to display an emtpy string.
How can this be done ?
Example
Table vaccinne
id
name
1
Moderna
2
Comirnaty
3
Janssen
Table patient
id
name
vaccine_id
1
john
1
2
kermit
2
3
jessica
I'm looking for a query to produce:
id
name
vaccine_id
1
john
Moderna
2
kermit
Comirnaty
3
jessica
If I understand correctly, you want a left join starting with foo:
SELECT *
FROM foo f LEFT JOIN
vac v
ON f.vac_1 = mv.id
I have two tables that have similar structure but I need to obtain all information relative to zip code.
tableA
zip_code location
1 A
2 C
2 D
3 E
4 F
5 G
tableB
zip_code location n
2 A 1
2 C 2
2 D 3
3 A 4
3 E 5
4 F 6
4 H 7
6 Y 8
As you can see, one locatıon can have multiple zip_code. So, I have to use zip_code and location for the join condition. When I applied left join, I couldn't manage to fill NULL parts. My strategy to fill it is like this:
If zip_code in the tableA is not in the tableB, I search for the location names and choose the n based on the minimum difference between zip_codes.
If zip_code and location in the tableA are not in the tableB, I want to search for n based on the minimum difference between zip_codes, and if there are multiple possibilities based on this I want to choose the minimum n.
NOTE: When looking at the difference between zip_codes, if there is a situation where they are equal I want to get the smaller number. For example, 5 could get 4 and 6 in terms of minimum difference but I want to go with 4 and look other conditions then.
The resulting table should be something like this:
zip_code location n
1 A 1
2 C 2
2 D 3
3 E 5
4 F 6
5 G 6
I know it is a bit complicated but I can explain the fuzzy parts with more details
This sounds like an OUTER APPLY:
select a.*, b.n
from tableA a outer apply
(select top (1) b.*
from tableB b
order by (case when b.zip_code = a.zip_code and b.location = a.location
then -1
when b.location = a.location
then abs(b.zip_code - a.zip_code)
else abs(b.zip_code - a.zip_code)
end),
b.n
) b;
Here is a db<>fiddle.
I have a table below which stores Connections between 2 person
TABLE (CONNECTION)
ID | REQUEST_PERSON | REQUESTEE_PERSON
I would like to build a VIEW which gets the REQUEST_PERSON, REQUESTEE_PERSON and MUTUAL_CONNECTION_COUNT(other common connections count between them). Any help is appreciated
For Example if we have a table data as below
ID | REQUEST_PERSON | REQUESTEE_PERSON
1 A B
2 A C
3 B C
4 D B
5 D A
6 A E
7 B E
8 A F
9 C G
I need a VIEW display below
ID | REQUEST_PERSON | REQUESTEE_PERSON | MUTUAL_CONNECTION_COUNT
1 A B 3
2 A C 1
3 B C 1
4 D B 1
5 D A 1
6 A E 1
7 B E 1
8 A F 0
9 C G 0
This is rather tricky. Here is code that does what you want:
select c.*,
(select count(*)
from (select v.person2
from connections c2 cross apply
(values (c2.REQUESTEE_PERSON, c2.REQUEST_PERSON), (c2.REQUEST_PERSON, c2.REQUESTEE_PERSON)
) v(person1, person2)
where v.person1 IN (c.Request_Person, c.Requestee_Person)
group by v.person2
having count(*) = 2
) v
) in_common
from connections c
order by id;
Here is a SQL Fiddle.
The essence of the problem is finding people who are connected to both people in each row. Your connections are unidirectional, which makes the logic hard to express -- C could be either the first or second person in either connection.
Arrgh!
So, the innermost subquery adds reverse links to the graph. Then, it can focus on filtering by the first person -- who has to match the persons in the outer query. The second person is the one that might be in common.
The inner aggregation is just summarizing by the second person. It filters using having count(*) = 2 to indicate that both people in the outer query need to be connected to the second person in the inner query. The count(*) assumes that you have no duplicates.
Then, these are counted, which is the value you want.
Tables:
Client
CID Name
1 A
2 B
3 C
4 D
5 E
6..(And so on)
Visit
VID CID type
1 1 Med
2 3 Non
3 2 Non
4 6 Med
5 4 Med
6..(And so on)
Payment
PID CID amount
1 1 10
2 1 20
3 2 30
4 2 40
5 3 50
6..(And so on)
Desired Output:
CID Name type amount
1 A Med 10
1 A Med 20
4 D Med NULL
(And so on..)
Query:
SELECT DISTINCT
C.client_id
,C.name
,V.type
,P.payment
FROM Clients C
INNER JOIN Visit V
ON C.cid=V.cid
LEFT JOIN Payment P
ON V.cid=P.cid
I used a LEFT JOIN because I wanna see who made payments and who didn't.
Question: Do LEFT JOINS (or outer joins) pull in data based on the common id's in the CID of the left table resulting from preceding INNER JOINS(The common result set)? Or do they consider ALL the id's in the left table and ignore the INNER JOINS results altogether?
I only want payment details of the clients existing in the inner joins and not outside it.
The LEFT JOIN will only run on rows that the INNER JOIN returns, or the common data set as you mention.
That is regardless of what the LEFT JOIN will return, the INNER JOIN is going to limit the result set based on Visit V ON C.cid=V.cid
This venn diagram shows the results that will be selected, the blue area is your data that will be returned. The order of the joins does not matter.
I would like to know what's the logic for multiple joins (for example below)
SELECT * FROM B returns 100 rows
SELECT B.* FROM B LEFT JOIN C ON B.ID = C.ID returns 120 rows
As I know using left join will returns any matching data from the left table which is B if data are found for both table. But how come when using left join, it returns more data than table B itself?
What am I do wrong or misunderstood here? Any guidance are very appreciated. Thanks in advance.
Let be table B:
id
----
1
2
3
Let be table C
id name
------------
1 John
2 Mary
2 Anne
3 Stef
Any id from b is matched with ids from c, then id=2 will be matched twice. So a left join on id will return 4 rows even if base table B has 3 rows.
Now look at a more evil example:
Table B
id
----
1
2
2
3
4
table C
id name
------------
1 John
2 Mary
2 Anne
3 Stef
Every id from b is matched with ids from c, then first id=2 will be matched twice and second id=2 will be matched twice so the result of
select b.id, c.name
from b left join c on (b.id = c.id)
will be
id name
------------
1 John
2 Mary
2 Mary
2 Anne
2 Anne
3 Stef
4 (null)
The id=4 is not matched but appears in the result because is a left join.
Look at the following example :
B = {1,2}
C = {(1,a),(1,b),(1,c),(1,d),(1,e)}
The result of B left join C will be :
1 | a
1 | b
1 | c
1 | d
1 | e
2 | null
The number of rows in the result is definitely larger than rows in B (2).
In general the number of rows in result of B left join C is bounded by B.size + C.size and not only by B.size as you think...
As per your query it do the join to B Table with C and B table is Left Table so it will display all the records of Left table in our case it is B and related from other Table in our Case it is C.