TableA
ID MatchID1 MatchID2
1 1002 120
3 1003 141
5 1006 150
6 1008 140
TableB
ID MatchID1 MatchID2 Status
1 1002 120
2 1002 120
3 1002 120
4 1003 200
5 1006 150
6 1008 150
7 1008 140
I want to populate TableB col = status with 'FAIL' if:
ALL matchID2 for its MatchID1 from tableB is not equal to the matchID2 for its corresponding MAatchID1 in tableA
In this case, tableB: 120 corresponds to 1002, same is true for tableA, hence not fail.
Expected result:
ID MatchID1 MatchID2 Status
1 1002 120 NULL
2 1002 120 NULL
3 1002 120 NULL
4 1003 200 FAIL
5 1006 150 NULL
6 1008 150 FAIL
7 1008 140 FAIL
Note:
If even one record(match02) is not matching, fail whole set for match01. like for id 6&7 in tableB. Thanks in advance.
UPDATE a
SET Status = 'FAIL'
FROM TableA a
INNER JOIN (
SELECT a.MatchID1
FROM TableA a
INNER JOIN b ON a.MatchID1 = b.MatchID1 AND a.MatchID2 <> b.MatchID2
GROUP BY a.MatchID1
) x ON a.MatchID1 = x.MatchID1
update B
set status = 'FAIL'
From tableB B
INNER JOIN (SELECT B.matchID1 FROM TableB B
GROUP BY B.matchID1
HAVING MAX(matchID1)<> MIN(MatchID2)) B1
ON B.matchid1 = B1.MatchID1
UPDATE B
SET Status = 'FAIL'
FROM TableB B
INNER JOIN TableA A
ON A.MatchID1 = B.matchID1
WHERE A.matchID2 <> B.matchID2
re-reading.. still don't know what you asked...
suggest breaking down your effort into smaller chunks.
it seems you need several things:
a small query to get just the rows from the first table that do or do not have different match numbers. write that.
a small query to find if match number from the second table are found in the first table. write that.
an update that sets values based on the first two queries.
hth
I think you are looking for an update via a join. Try this;
UPDATE TableB
SET TableB.Status = CASE WHEN TableA.ID IS NULL THEN 'FAIL' ELSE NULL END
FROM TableB
LEFT JOIN TableA
ON TableB.MatchID1 = TableA.MatchID1
AND TableB.MatchID2 = TableA.MatchID2
You didn't say which RDBMS you are using, the above is for SQL Server.
Related
I have 2 tables
table1
ID VendorID
100 11190
200 99999
table2
ID VendorID
100 11190
100 11190
200 12523
200 53266
My expect result and my goal if ID and VendorID from table1 match with ID and VendorID from table2 then flag NO
table1ID table1Vendor table2ID table2Vendor Code
100 12345 100 12345 No
100 12345 100 12345 No
100 12345 100 45678 No
200 56489 200 11111 Use
200 56489 200 22222 Use
My query
SELECT a.id as table1ID, a.vendorid as table1Vendor, b.id as table2ID, b.Vendorid as table2Vendor
, case
when a.vendorid <> b.Vendorid
then 'Use' else 'No'
end as Code
FROM table_1 a
JOIN table_2 b on a.id = b.id
But I got
table1ID table1Vendor table2ID table2Vendor Code
100 12345 100 12345 No
100 12345 100 12345 No
100 12345 100 45678 Use
200 56489 200 11111 Use
200 56489 200 22222 Use
You can see row 3 is incorrect, should code as NO cause 12345(table1vendor) still match with 12345(table2vendor)
Not sure why, need some help. Thank you.
You are only checking the same row for a match, but according to your logic you need to check all rows, therefore you need another sub-query.
SELECT a.ID AS table1ID, a.VendorID AS table1Vendor, b.ID AS table2ID, b.VendorID as table2Vendor
, CASE WHEN EXISTS (SELECT 1 FROM table_2 b1 WHERE b1.id = a.ID AND b1.VendorID = a.VendorID) THEN 'No' ELSE 'Use' END AS Code
FROM table_1 a
JOIN table_2 b ON a.ID = b.ID;
I have a table with records of the same type with ID's and a grouping. I need to update the id's of table 1 into table 2 based on the record id from largest to smallest using the position.
Table 1
ID
Group
Name
1
A
Apple
2
A
Apple
3
B
Apple
4
B
Apple
Table 2
ID
recordid
position
group
1
1
250
A
2
2
350
A
3
null
450
A
4
null
550
A
5
3
250
B
6
4
350
B
7
null
450
B
8
null
550
B
update table2
set recordid=T1.ID
From Table1 T1
join Table2 T2 on T2.Group=T1.Group
This isn't distinct so I don't think it's right, but I can't figure it out.
where ?????
the problem is you have multiple Id per group , so you have to choose one :
update table2
set recordid= ( select top 1 T1.ID
From Table1 T1
join Table2 T2 on T2.Group=T1.Group
)
where recordid is null
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
I have following data
Components
componentid title
1 houseRent
2 medical
3 Travelling Allowance
empPayrollMaster
MasterID EmployeeID SalaryMonthID
1 101 1
2 102 1
3 103 1
empPayrollDetail
DetailID MasterID ComponentID amount
1 1 1 100
2 1 2 500
3 2 1 300
4 2 3 250
5 3 1 150
6 3 2 350
7 3 3 450
Required Output
EmployeeID MasterID ComponentID amount
101 1 1 100
101 1 2 500
101 1 3 0
102 2 1 300
102 1 2 0
102 2 3 250
103 3 1 150
103 3 2 350
103 3 3 450
To get the required output if i do left outer join between components and empPayrollDetail I get null in EmployeeID and MasterID and amount Columns. How to modify left join to get the required output
You need to do a CROSS JOIN on Components and empPayrollMaster to generate first all combination of employees and components. Then, do a LEFT JOIN on empPayrollDetail to achieve the result, using ISNULL(amount, 0) for NULL amounts.
SQL Fiddle
SELECT
epm.EmployeeID,
epm.MasterID,
c.ComponentID,
amount = ISNULL(epd.amount, 0)
FROM empPayrollMaster epm
CROSS JOIN Components c
LEFT JOIN empPayrollDetail epd
ON epd.MasterID = epm.MasterID
AND epd.ComponentID = c.ComponentID
Try this
select empPayrollMaster.EmployeeID,empPayrollMaster.MasterID,
Components.componentid,isnull(empPayrollDetail.amount,0)
from empPayrollMaster
left join Components
on empPayrollMaster.EmployeeID is not null
left join empPayrollDetail
on empPayrollDetail.MasterID = empPayrollMaster.MasterID
and empPayrollDetail.ComponentID = Components.componentid
Try this way
select c.EmployeeID,d.MasterID,c.ComponentID,isnull(d.amount,0) as amount from (
select * from Components a
Cross join empPayrollMaster b) c
left outer join empPayrollDetail d on d.componentid =c.componentid
As you want the component amount for each employee in the master table you should use a insull(payrole_detail.amount,0) or, as #Turophile pointed out, the SQL standard function coalesce(payrole_detail.amount,0) for the amounts column.
SELECT Customers.CustomerName, Orders.OrderID
FROM Customers
INNER JOIN Orders
ON Customers.CustomerID=Orders.CustomerID
ORDER BY Customers.CustomerName;
I have a SQL database with two tables
TableA (ID, State, Value)
1 England 20
2 France 50
3 USA 40
4 ........
5 ........
and
TableB (ID, username, age, stateID)
1 John 15 1
2 Adam 20 2
3 Jane 40 3
4 Scott 50 1
5 Edwin 60 2
6 Alex 20 3
7 Olsen 30 1
8 ...........
9 ...........
What I need is to update TableB by setting the age for all users
from England to be 20
and from France to be 50
and so on...
update tableB
set age = (select tableA.value from tableA where tableA.StateID=TableB.id)
I like this form below:
update b set
age = a.value
from tableB b
join tableA a on a.id = b.stateId
because you can write it this way (at last in SQL Server Management Studio):
update b set
age = a.value
--select b.age, a.value, b.*, a.*
from tableB b
join tableA a on a.id = b.stateId
then highlight the part from select ... to the end of query and execute it (F5) to check what you are going to change (value before and after).