I have a query and I want to look up the values from other table as a reference but not mess up my current query results. I think I have to use a Outer Left Join, but not sure how to incorporate that with my current query.
My current query looks similar to this:
SELECT a.primary_key,
a.phase,
b.project_number,
c.LENGTH,
d.color
FROM TableA a,
TableB b,
TableC c,
TableD d
WHERE c.primary_key = a.PROJECT_ID
AND b.primary_key = a.PROJECT_ID
AND b.primary_key = d.project_ID
AND (c.date IS NULL OR c.number IS NULL)
AND d.color IN ('black','red','blue')
ORDER BY 1
Now, that gives me a table of 50 results. 'TableContacts' has the look up value to my b.project_number. So say my table of 50 results, only 10 of them have b.project_number, I need the lookup values from 'TableContacts' to also show in my results, but I don't want that to affect my results and cut it down to 10, I still need my original 50 results, just with that additional information. Help?
Just add the CONTACTS table to your joins:
SELECT a.primary_key,
a.phase,
b.project_number,
c.LENGTH,
d.color,
ct.lookup_value --<< this is from the CONTACTS table
FROM TableA a
JOIN TableB b ON b.primary_key = a.PROJECT_ID
JOIN TableC c ON c.primary_key = a.PROJECT_ID
JOIN TableD d ON b.primary_key = d.project_ID
LEFT JOIN contacts ct ON ct.some_column = b.project_Number --<< this is the outer join to the CONTACTS table
WHERE (c.date IS NULL OR c.number IS NULL)
AND d.color IN ('black','red','blue')
ORDER BY 1
As you obfuscated your table and column names it's hard to guess how exactly the join condition on the CONTACTS table should look like.
You could use this approach:
Create a table with the results of your current query:
create table t1 as
SELECT a.primary_key,
a.phase,
b.project_number,
c.LENGTH_col,
d.color
FROM a,b,c,d
WHERE c.primary_key = a.PROJECT_ID
AND b.primary_key = a.PROJECT_ID
AND b.primary_key = d.project_ID
AND (c.date_col IS NULL OR c.number_col IS NULL)
AND d.color IN ('black','red','blue')
ORDER BY 1;
Use a union to get the desired results:
select t1.primary_key, t1.phase, t1.project_number, t1.length_col, t1.color, TableContacts.lookup_column
from t1, TableContacts
where t1.project_number = TableContacts.project_number
UNION
select t1.primary_key, t1.phase, t1.project_number, t1.length_col, t1.color, null
from t1 where t1.project_number is null;
Illustration by creating dummy data:
select * from a;
PRIMARY_KEY | PROJECT_ID | PHASE
1 100 Phase-1
2 200 Phase-2
3 300 Phase-3
4 400 Phase-4
5 500 Phase-5
select * from b;
PRIMARY_KEY | PROJECT_NUMBER
100 null
200 2000
300 3000
400 null
500 5000
select * from c;
PRIMARY_KEY | NUMBER_COL | LENGTH_COL | DATE_COL
100 null 99 null
200 null 99 null
300 null 99 null
400 null 99 null
500 null 99 null
select * from d;
PROJECT_ID | COLOR
100 black
200 red
300 blue
400 black
500 yellow
select * from TableContacts;
PROJECT_NUMBER | LOOKUP_COLUMN
1000 l-1000
2000 l-2000
3000 l-3000
4000 l-4000
5000 l-5000
Existing query in question returns this:
SELECT a.primary_key,
a.phase,
b.project_number,
c.LENGTH_col,
d.color
FROM a,b,c,d
WHERE c.primary_key = a.PROJECT_ID
AND b.primary_key = a.PROJECT_ID
AND b.primary_key = d.project_ID
AND (c.date_col IS NULL OR c.number_col IS NULL)
AND d.color IN ('black','red','blue')
ORDER BY 1;
PRIMARY_KEY | PHASE | PROJECT_NUMBER | LENGTH_COL | COLOR
1 Phase-1 null 99 black
2 Phase-2 2000 99 red
3 Phase-3 3000 99 blue
4 Phase-4 null 99 black
The goal is to populate the lookup_column where project_number is not null. Running the union query provided at start of answer:
select t1.primary_key, t1.phase, t1.project_number, t1.length_col, t1.color, TableContacts.lookup_column
from t1, TableContacts
where t1.project_number = TableContacts.project_number
UNION
select t1.primary_key, t1.phase, t1.project_number, t1.length_col, t1.color, null
from t1 where t1.project_number is null;
PRIMARY_KEY | PHASE | PROJECT_NUMBER | LENGTH_COL | COLOR | LOOKUP_COLUMN
1 Phase-1 null 99 black null
2 Phase-2 2000 99 red l-2000
3 Phase-3 3000 99 blue l-3000
4 Phase-4 null 99 black null
Related
I have 3 tables. 1st table stores coil information, 2nd table store coil information in transport and 3rd stores reserved coils.
coils
ID
SERIAL
COLOR
MATERIAL
STATUS
1
12345
5
1
2
2
12346
4
1
3
3
12347
3
1
2
coils_in_transport
ID
SERIAL
COLOR
MATERIAL
STATUS
1
f34S5
5
1
2
2
A23GG6
4
1
3
3
ff2S147
3
1
2
reserved_coils
ID
NUMBER
QUANTITY
START
END
1
12345
25
2022-05-01
2023-05-01
3
12347
252
2022-01-01
2023-05-01
4
A23GG6
33
2022-04-01
2023-05-01
5
ff2S147
35
2022-08-01
2023-05-01
I need to write query that will get all reserved coils (reserved_coils) that has status 2 and for each coil I need to join tables for materials and colors
material
ID
NAME
1
color
ID
NAME
I wrote query but it doesn't show coils in transport that are reserved, here is what I tried
SELECT a.QUANTITY, a.START, a.END, b.name, m.name
FROM reserved_coils a
LEFT JOIN coils b ON a.number = b.serial
LEFT JOIN coils_in_transport c ON a.number = c.serial
LEFT JOIN material m ON b.material = m.id
LEFT JOIN material b ON b.material = b.id
where b.status = 2 and c.status = 2
To get all coils and colis_in_transport you need to use UNION for SELECT statements for both tables, each filtered by status value, which should be equal to 2. Then you need to do a JOIN between reserved_coils and the result of UNION to filter out reserved_coils rows.
Your query would be like this
SELECT
r.quantity,
r.start,
r.[end],
c.serial,
material.name AS material,
color.name AS color
FROM reserved_coils r
JOIN (
SELECT * FROM coils WHERE status = 2
UNION
SELECT * FROM coils_in_transport WHERE status = 2
) c ON r.number = c.serial
LEFT JOIN material ON material.id = c.material
LEFT JOIN color ON color.id = c.color
Demo
If you want left join twice on same table, this might help
SELECT a.QUANTITY, a.START, a.[END], isnull(b.serial,c.serial) serial,isnull(c1.name,c2.name) color, isnull(m.name,n.name) material
FROM reserved_coils a
LEFT JOIN coils b ON a.number = b.serial
LEFT JOIN coils_in_transport c ON a.number = c.serial
LEFT JOIN material m ON b.material = m.id
LEFT JOIN material n ON c.material = n.id
LEFT JOIN color c1 on b.color=c1.id
LEFT JOIN color c2 on c.color=c2.id
where isnull(b.status,c.status) = 2
DB<>Fiddle
I want to write a sql script which fetches data from 2 tables one is parent and second is child table
Bid
BidId | Code | Date
1 | H | 2022-05-12
2 | B | 2022-05-13
BidResult
BidResultId | BidId | Emi
12 | 1 | 50
13 | 1 | 20
14 | 2 | 30
Bid and BidResult
i want fetch column Date,Code,BidId from Bid Table
and BidResultId, EMI from BidResult but want a another column of Minimum EMI
from above example i want to fetch for bidId 1
Code H,date 2022-05-12,BidResultId 12, Emi 50 and Min Emi between 50 and 20 which is 20
so i have written following query
Select B.BidId,BR.EMI As Installment,
(Select Min(BR.EMI ) from BidResult BR
Inner Join Bid B on B.BidId = BR.BidResultId
where B.BidId = 5) As MinInstallment,
B.Code,
BR.BidResultId,
CONVERT(DATE, B.Date) As BidDate
from Bid B
Inner Join BidResult BR On B.BidId = BR.BidId
where B.BidId= 5 and B.TypeId = 1
All Field are starightforward except the minimum EMI value from BidResult for that BidId
please check the query and suggest if any modifications
Solution 1: With group by
select BID, min(EMI) EMI
into #temp
from BIDResult
group by BID
select b.Date, b.Code, b.BidId, br.BidResultId, br.EMI
from BID b
inner join #temp on t.BID = b.BID
inner join BIDResult br on br.BID = t.BID and br.EMI = t.EMI
Solution 2: Without group by
select *, ROW_Number() over(PARTITION by BID order by EMI) RowNumber
into #temp
from BIDResult
select b.Date, b.Code, b.BidId, br.BidResultId, br.EMI
from BID b
inner join #temp t on t.BID = b.BID and t.RowNumber = 1
I have 2 tables with a 1:n relationship.
I want to join them without repeating (duplicating) the values from the one table.
First, I have a table with budgets:
id name budget
1 John 1000
2 Kim 3000
And second I have a table of spendings:
id amount
1 112
1 145
1 211
The result should look like this:
id name budget amount
1 John 1000 112
1 null null 145
1 null null 211
2 Kim 3000 null
Output could also be: (this is not important)
id name budget amount
1 null null 112
1 John 1000 145
1 null null 211
2 Kim 3000 null
Is this possible with SQL?
Here a join that repeats the values:
create temporary table a (id1 int,name varchar(10),budget int);
insert into a (id1,name,budget) values(1,'Maier',1000),(2,'Mueller',2000);
create temporary table if not exists b (id2 int,betrag int);
insert into b (id2,betrag) values(1,100),(1,133),(1,234);
select * from a left join b
on a.id1=b.id2
;
The keyword DISTINCT is used to eliminate duplicate rows from a query result:
select distinct b.id, b.name, b.budget, s.amount
from budgets b left join spendings s
on b.id = s.id;
You can also use Group By clause which works similarly like Distinct.In that case,
select b.id, b.name, b.budget, s.amount
from budgets b left join spendings s
on b.id = s.id
group by b.id, b.name, b.budget, s.amount;
create table a (id1 int,name varchar(10),budget int)
insert into a (id1,name,budget) values(1,'Maier',1000)
insert into a (id1,name,budget) values(2,'Mueller',2000)
create table b (id2 int,betrag int)
insert into b (id2,betrag) values(1,100)
insert into b (id2,betrag) values(1,133)
insert into b (id2,betrag) values(1,234)
insert into b (id2,betrag) values(2,300)
insert into b (id2,betrag) values(2,400)
select a.id1, CASE WHEN c.themin IS NOT NULL THEN a.name ELSE NULL END AS [name],
CASE WHEN c.themin IS NOT NULL THEN a.budget ELSE NULL END AS [budget],
b.*
from a
LEFT join b on a.id1=b.id2
LEFT OUTER JOIN (SELECT MIN(betrag) AS [themin], id2 FROM b GROUP BY id2) c ON a.id1 = c.id2 AND b.betrag = c.themin
I have 2 tables A, B
Table A:
ID Value1 Value2
------------------------
1000 10 25
1001 4 12
1002 2 6
1003 1 8
Table B:
ID Value3 Value4
------------------------
1000 51 12
1003 3 10
What I need is to show the below result:
ID Value1 Value2 Value3 Value4
-----------------------------------------
1000 10 25 51 12
1001 4 12 NULL NULL
1002 2 6 NULL NULL
1003 1 8 3 10
The query I've tried:
SELECT I.AgentId AS AGENT
,COUNT(I.Indice) AS [Number of Inbound calls]
,AVG(I.WrapupDuration) AS [AVG Wrapup IN]
,COUNT(O.Indice) AS [Number of Out calls]
,AVG(O.WrapupDuration) AS [AVG Wrapup Out]
FROM [HN_Ondata].[dbo].[vwInboundCalls] I
LEFT JOIN [HN_Ondata].[dbo].vwOutboundCalls O
ON I.AgentId = O.AgentId
GROUP BY I.AgentId
You just need a LEFT JOIN and a query like below, you don't need another table:
SELECT *
FROM TABLE_A A
LEFT JOIN TABLE_B B ON A.ID = B.ID
You have to use LEFT JOIN to achieve your goal.
SELCT * FROM TABELA LEFT JOIN TABLEB ON TABLEA.ID = TABLEB.ID
You should use left join
SELECT
*
FROM
TABLEA T1
LEFT JOIN
TABLEB T2
ON
T1.ID = T2.ID
The LEFT JOIN keyword returns all rows from the left table (table1), with the matching rows in the right table (table2). The result is NULL in the right side when there is no match.
I have a table like this
Table A:
Id Count
1 4
1 16
1 8
2 10
2 15
3 18
etc
Table B:
1 sample1.file
2 sample2.file
3 sample3.file
TABLE C:
Count fileNumber
16 1234
4 2345
15 3456
18 4567
and so on...
What I want is this
1 sample1.file 1234
2 sample2.file 3456
3 sample3.file 4567
To get the max value from table A I used
Select MAX (Count) from A where Id='1'
This works well but my problem is when combining data with another table.
When I join Table B and Table A, I need to get the MAX for all Ids and in my query I dont know what Id is.
This is my query
SELECT B.*,C.*
JOIN A on A.Id = B.ID
JOIN C on A.id = B.ID
WHERE (SELECT MAX(COUNT)
FROM A
WHERE Id = <what goes here????>)
To summarise, what I want is Values from Table B, FileNumber from Table c (where the count is Max for ID from table A).
UPDATE: COrrecting table C above. Looks like I need Table A.
I think this is the query you're looking for:
select b.*, c.filenumber from b
join (
select id, max(count) as count from a
group by id
) as NewA on b.id = NewA.id
join c on NewA.count = c.count
However, you should take into account that I don't get why for id=1 in tableA you choose the 16 to match against table C (which is the max) and for id=2 in tableA you choose the 10 to match against table C (which is the min). I assumed you meant the max in both cases.
Edit:
I see you've updated tableA data. The query results in this, given the previous data:
+----+---------------+------------+
| ID | FILENAME | FILENUMBER |
+----+---------------+------------+
| 1 | sample1.file | 1234 |
| 2 | sample2.file | 3456 |
| 3 | sample3.file | 4567 |
+----+---------------+------------+
Here is a working example
Using Mosty’s working example (renaming the keyword count to cnt for a column name), this is another approach:
with abc as (
select
a.id,
a.cnt,
rank() over (
partition by a.id
order by cnt desc
) as rk,
b.filename
from a join b on a.id = b.id
)
select
abc.id, abc.filename, c.filenumber
from abc join c
on c.cnt = abc.cnt
where rk = 1;
select
PreMax.ID,
B.FileName,
C2.FileNumber
from
( select C.id, max( C.count ) maxPerID
from TableC C
group by C.ID
order by C.ID ) PreMax
JOIN TableC C2
on PreMax.ID = C2.ID
AND PreMax.maxPerID = C2.Count
JOIN TableB B
on PreMax.ID = B.ID