How to update Two Columns at the same time with different queries - sql

I have this after insert trigger which updates two different columns based on a join. Basically it turns an Id into a value. This works fine except when one of the Ids does not match (ie, it's zero for the default) Then neither is updated. If the join fails, it should just insert null.
CREATE TRIGGER [AfterHistoryInsert]
ON [Jet].[HistoryEntity]
FOR INSERT
AS
BEGIN
Update t1 Set t1.OldValue = t2.Value, t1.NewValue = t3.Value
From Jet.HistoryEntity t1
join Jet.LookupListItemEntity t2 on Cast(t1.OldValue as int) = t2.Id
join Jet.LookupListItemEntity t3 on Cast(t1.NewValue as int) = t3.Id
inner join inserted i on i.Id = t1.Id
where t1.FieldName like '%Id'
END
Greg

Try left outer join instead join

If you are updating into a bigger table, one of the suggestion will be:
- Selecting all the columns that you want to update(In your case Value) into temp table
- Update Statement by using left outer join to temp table.

Related

Join table in oracle database

I have 2 tables that showing data Item master and BOM. I would like to join the tables between Item master as T1 and BOM as T2 and the additional table for table BOM as T3. Item master table containing ITM_CD, ITM_TYP (1,2,3,4) where each ITM_TYP represents a code for the first digit on ITM_CD. The thing that I want is like the picture below
CHILD_CD2 value replace to CHILD_CD1 value. So the data should be like this. What query should I fix ? I am very new using oracle query.
Here is mycode;
SELECT DISTINCT
T1.ITM_CD,
T2.C_ITM_CD AS CHILD_CD1,
T3.C_ITM_CD AS CHILD_CD2
FROM CM_HINMO_ALL T1
INNER JOIN (SELECT P_ITM_CD, C_ITM_CD, BOM_PTN FROM SM_BOM_ALL) T2
ON T1.ITM_CD = T2.P_ITM_CD
LEFT JOIN (SELECT P_ITM_CD, C_ITM_CD, BOM_PTN FROM SM_BOM_ALL) T3
ON T2.C_ITM_CD = t3.P_ITM_CD
WHERE 0=0
AND T2.BOM_PTN IN (1)
AND T1.ITM_TYP IN (1,2)
AND T1.ITM_CD = '110100370'
ORDER BY 2
Just use Case expression to replace the values.
SELECT ITM_CD, CASE WHEN CHILD_CD2 IS NULL THEN CHILD_CD2 ELSE CHILD_CD1 END AS CHILD_CD1
FROM TABLE1
If I understood, you want child_cd2 value should taken precedence over child_cd1 if available. If this assumption is right then we can use coalesce which returns the fist non null expression to achieve the same.
SELECT DISTINCT
T1.ITM_CD,
COALESCE(T3.C_ITM_CD,T2.C_ITM_CD) AS CHILD_CD1
FROM CM_HINMO_ALL T1
INNER JOIN SM_BOM_ALL T2
ON T1.ITM_CD = T2.P_ITM_CD
LEFT JOIN SM_BOM_ALL T3
ON T2.C_ITM_CD = t3.P_ITM_CD
WHERE T2.BOM_PTN IN (1)
AND T1.ITM_TYP IN (1,2)
AND T1.ITM_CD = '110100370'
ORDER BY 2

Return data when the OR operator conditions are true in sql server

I have the following query. Currently it checks on two conditions:
if one condition is true it will return the results for the first statement (t1.ticket=t2.ticket and ( t1.type=t2.type)
if this result is false then it will return results for the next condition ( t1.code=t2.code).
It does this is because sometimes this condition columns (t1.ticket=t2.ticket and ( t1.type=t2.type)) are equal to null and some times this condition colums ( t1.code=t2.code) are null thats why it switches between both.
But now what i noticed is that sometimes both the conditions return true and because of the OR statement its ignoring one of the conditions.
How do i return results for both of those conditions if they both there conditions are met? If its not met then they must return the one condition that matches.
select t1.name
,t1.ID
,t1.type
,t2.TicketID
,t2.Account
,t1.code
from table 1 t1
inner join table 2 t2
on (t1.ticketID=t2.ticketID and t1.type=t2.type)
or ( t1.code=t2.code)
left join table 3 t3
on t2.Res=t3.res
left join table 4 t4
on t3.IdDetail=t4.idDetail
you can try by using left join
select t1.name
,t1.ID
,COALESCE(t2.Ticket,t22.Ticket) as Ticket
,COALESCE(t2.Account,t22.Account) as Account
,COALESCE(t2.code,t22.code) as code
,t22.type
,t3.res
,t1.type
from table1 t1 left join table2 t2 on (t1.ticket=t2.ticket and t1.code=t2.code)
left join t22 on ( t1.type=t22.type)
left join table3 t3 on t2.Res=t3.res
left join table4 t4 on t3.IdDetail=t4.idDetail
If you want both result of table2 then no need use COALESCE function
My suggestion is to add a calculated column as hash of ticket, on both table1 and table2 code and type on all the tables, then using it as a new 'surrogate' key, a trigger to generate it each time a row is updated.
ALTER TABLE T1 ADD
NEW_KEY AS (hashbytes('SHA1',CONCAT(TICKET,CODE,TYPE)))
ALTER TABLE T2 ADD
NEW_KEY AS (hashbytes('SHA1',CONCAT(TICKET,CODE,TYPE)))
UPDATE TABLE T2 SET NEW_KEY = hashbytes('SHA1',CONCAT(TICKET,CODE,TYPE)) WHERE NEW_KEY IS NULL
UPDATE TABLE T1 SET NEW_KEY = hashbytes('SHA1',CONCAT(TICKET,CODE,TYPE)) WHERE NEW_KEY IS NULL

Is there any alternative way of achieving below logic in sql?

I have two tables -> tb1 and tb2.
I am performing left join operation on these tables using ID column and also i have one more condition such as one column is not equal to other column .
Below is sample code
select * from tb1 LEFT JOIN tb2 ON tb1.id=tb2.id AND tb1.pid!=tb2.pid;
I am able to get results from above query.
But i need to know is there any alternate ways to get same result using sql.?
The actually SQL standard uses <> instead of !=.
select * from tb1 LEFT JOIN tb2 ON tb1.id=tb2.id AND tb1.pid<>tb2.pid;
It seems to you not equal not working because of your join and join condition.
if we create two tables and create like your query
create table t1(id int,pid int);
create table t2 (id int,pid int );
insert into t1 values(1,2),(2,3),(3,4);
insert into t2 values(1,2),(2,3),(3,4);
select t1.* from t1 left join
t2 on t1.id=t2.id and
t1.pid!=t2.pid
order by t1.id
id pid
1 2
2 3
3 4
It returns all the values of 1st table, because LEFT JOIN returns all records from the left table (table1), and the matched records from the right table (table2). The result is NULL from the right side, if there is no match.
But if you put inner join in the same it will not return any row. so i think problem is not in the "not equal operator"

Conditional Join if Exists

I need to join two tables together based on a three-column key stack. The problem is sometimes one of the key columns is translated and mapped differently in another table. I will attempt to example my issue using code:
select t1.TQ
from table1 t1
left join table2 t2 on t1.comp_cd = t2.comp_cd and t1.plcy_frm = t2.plcy_frm
and t1.val_cd = t2.val_cd
The columns "comp_cd" and "plcy_frm" are fine, however the problem is with val_cd. Sometimes the val_cd in table2 does not map correctly to table1 and must go through a third table, table3. Table3 structure is below:
Val_Cd Mapped_Val_Cd
A123 A564
So -> I need to join on Mapped_Val_Cd value when it exists in Table3, but join on Val_Cd from Table2 when Val_Cd does not exist in Table3.
I hope this makes sense - I have tried Case when exists syntax but cannot get that to work.
Assuming there are no duplicates in table3, you can left join it in and then choose the value that you want in the on clause:
select t1.TQ
from table1 t1 left join
table3 t3
on t1.val_cd = t3.val_cd
table2 t2
on t1.comp_cd = t2.comp_cd and
t1.plcy_frm = t2.plcy_frm and
t1.val_cd = coalesce(t3.Mapped_Val_Cd, t2.val_cd);

In SQL Server, How to join two table having different column name and different data row?

Suppose I have two tables T1 & T2. I want resulting output table as O1 with help of a SQL query
T1 {SName}
T2 {VName}
O1 {SName, VName}
It seems like you want a cross join of the two tables to include all combinations of rows in T1 and T2. Try this:
Select SName, VName From T1 Inner Join T2 On 1=1
The number of rows you will get is the product of the number of rows in T1 and T2 each.
if you're not joining on anything and want a table of all possible combinations:
select SName, VName
into O1
from T1 cross join T2
if you have a column to join on:
select SName, VName
into O1
from T1 inner join T2 on T1.col = T2.col
Select record from T1 and T2 based on filtering criteria and then insert record in table O1 , use below query to create table O1 and inserting those records.
INSERT INTO O1(SNAME, VNAME)
SELECT(T1.SNAME, T2.VNAME)
From T1 Inner Join T2 On 1=1 //i.e WHERE T1.id=T2.T1_id
use WHERE to filter records
there are several ways of doing it.one easy way is:
select T1.SName,T2.VName from T1,T2;
i don't know if i am right, you can use cross join.
if you have two tables Players and GameScores then
SELECT* INTO O1 FROM GameScores CROSS JOIN Players will return all records where each row from the first table is combined with each row from the second table. Which also mean CROSS JOIN returns the Cartesian product of the sets of rows from the joined tables.
to get the above result as
T1 {SName}
T2 {VName}
O1 {SName, VName}
(SELECT * FROM T1,T2) as O1;
will definitely work if both the table have single value if not then you can select the
Particular column like T1.SName,T2.VName