SQL update joining 2 tables - sql

In MS Access I am trying to update 1 table based on a concatenation of columns NOT matching a concatenation of columns in another table. Here is what I need to do.
If ((Table1.A + Table1.B + Table1.C + Table1.D)
NOT EQUAL TO (Table2.E + Table2.F + Table2.G + Table2.H))
Then set Table1.error = x
I know this is some type of SQL join but I'm struggling with it.
Update:
Ok, I finally got something to work. This is what I have:
SELECT [Table1].[A] & [Table1].[B] & [Table1].[C] & [Table1].[D] AS Expr1
FROM Table1, Table2
WHERE ((([Table2].[E] & [Table2].[F] & [Table2].[G] & [Table2].[H])<>
[Table1].[A] & [Table1].[B] & [Table1].[C] & [Table1].[D]));
That'll run but it shows me every unmatched line. I need to search table 1 for any rows that don't exist in table 2 and only return those unmatched rows in table 1.

UPDATE (SELECT Table1.error
FROM Table1,
Table2
WHERE ((Table1.A + Table1.B + Table1.C + Table1.D)
NOT EQUAL TO (Table2.E + Table2.F + Table2.G + Table2.H)))
SET Table1.error = x

You could try an update join with on clause for the <> results
update T
set t.error = x
FROM Table1 AS T
INNER JOIN (
SELECT Table2.E + Table2.F + Table2.G + Table2.H as T2_RESULT
from Table2
) AS ON T2.T2_RESULT <> (Table1.A + Table1.B + Table1.C + Table1.D)

UPDATE Table1 AS T1
INNER JOIN Table2 AS T2
ON (Table1.A + Table1.B + Table1.C + Table1.D) NOT EQUAL TO (Table2.E + Table2.F + Table2.G + Table2.H))
set T1.error = x
It will update Table1.error with inner join Table2 on condition of columns' sum not equal.

Assuming field [E] in Table 2 can never be null, you can find your UNMATCHED Table 1 records by searching for Nulls after a Left Join:
SELECT [T1].[A] & [T1].[B] & [T1].[C] & [T1].[D] AS Concat1
FROM
[Table1] as T1
Left Join [Table2] as T2 ON
((([T2].[E] & [T2].[F] & [T2].[G] & [T2].[H]) = [T1].[A] & [T1].[B] & [T1].[C] & [T1].[D]))
WHERE
[T2].[E] is NULL;
This will return All your Table 1 records that don't have a matching Table 2 record.
You can call that query into your update.

I realized that the fields didn't need to be concatenated (they were concatenated in previous code so I assumed it was for a reason). So I did an unmatched query wizard with the 4 fields separately within the same query.

Related

Compare fields from different rows

First off I am using SQL Server.
I am joining a table on itself like in the example below:
SELECT t.theDate,
s.theDate,
t.bitField,
s.bitField,
t.NAME,
s.NAME
FROM table1 t
INNER JOIN table1 s ON t.NAME = s.NAME
If I take a random row (i.e. X) from the dataset produced.
Can I compare values in any field on row X to values in any field on row X-1 OR row X+1?
Example: I want to compare t.theDate on row 5 to s.theDate on row 4 or s.theDate on row 3.
Sample data looks like:
Desired results:
I want to pull all pairs of rows where the t.bitfield and s.bitfield are opposite and t.theDate and s.theDate are opposite.
From the image the would be row (3 & 4), (5 & 6), (7 & 8) ... etc.
I really appreciate any help!
Can it be done?
Varinant 1: It looks like you would like to use ranking function.
if objcet_id('tempdb..#TmpOrderedTable') is not null drop table #TmpOrderedTable
select *, row_number(order by columnlist, (select 0)) rn
into #TmpOrderedTable
from table1 t
select *
from #TmpOrderedTable t0
inner join #TmpOrderedTable tplus on t0.rn = tplus.rn + 1 -- next one
inner join #TmpOrderedTable tminus on t0.rn = tminus.rn - 1 -- previous one
Varinant 2:
To get scalar values you can use ranking function lag and lead. Or subquery.
Varinant 3:
You can use selfjoin, but you have to specify unique nonarbitary key if you don't want duplicates.
Varinant 4:
You can use apply.
Your question isn't too clear, so i hope it was your goal.
How about this?
WITH ts as (
SELECT t.theDate as theDate1, s.theDate as theDate2,
t.bitField as bitField1, s.bitField as bitField2,
t.NAME -- there is only one name
FROM table1 t INNER JOIN
table1 s
ON t.NAME = s.NAME
)
SELECT ts.*
FROM ts
WHERE EXISTS (SELECT 1
FROM ts ts2
WHERE ts2.name = ts.name AND
ts2.theDate1 = ts.theDate2 AND
ts2.theDate2 = ts.theDate1 AND
ts2.bitField1 = ts.bitField2 AND
ts2.bitField2 = ts.bitField1
);

Is there a more efficient query I can use

I want to know if theres a better way to script out this update statement:
update table A
set item = (select itemA + ' - ' + itemB from table B where id = 1),
temp = (select itemA from table B where id = 1)
where sid = (select sItemId from table B where id = 1)
Use JOINS to make it more efficient and Alias to make it more readable.
UPDATE A
SET A.item = B.itemA + ' - ' + B.itemB
,A.temp = B.itemA
FROM tableA A
INNER JOIN tableB B ON A.[sid] = B.sItemId
where B.id = 1
SQL Server specific syntax:
update a
set item = b.itemA + ' - ' + b.itemB,
temp = b.itemA
from tableA a
inner join tableB b on a.sid = b.sItemId
where b.id=1
Alternatively you can use MERGE:
merge into tableA as a
using tableB as b
on a.sid = b.sItemId and b.Id = 1
when matched then update set item = b.itemA + ' - ' + b.itemB, temp = b.itemA
;
The advantage of merge is that it is standard SQL syntax, and it will fail if an attempt is made to update the same record twice (the update with join will silently do only one of the updates). IIRC in later versions (with the respective compatibility level) update will fail as well. Also merge is more flexible.
It is of course better to use only one join instead of retrieving the same table (tableB) 3 times
UPDATE tableA
SET tableA.item =tableB. itemA + ' - ' + tableB.itemB,
tableA.temp = tableB.itemA ,
...
FROM tableA, tableB
WHERE tableA.sid= tableB.sItemId And tableB.id =1

Can someone explain me what is the difference between union All and join in oracle SQL

I am searching for this question since last 2 days what is the difference between UNION and JOIN. Specifically UNION ALL and Natural JOIN.
So I have 2 queries here
first one is
CREATE OR REPLACE VIEW VU_m1 AS
SELECT department_id,manager_id FROM employees
NATURAL JOIN departments ;
SELECT * FROM vu_m1;
and the second one is
CREATE OR REPLACE VIEW VU_m2 AS
SELECT department_id,manager_id FROM employees
UNION ALL
SELECT department_id,manager_id FROM departments;
SELECT * FROM vu_m2;
The result from both the query is exactly same.
So now what is the difference between UNION ALL and Natural JOIN
Details:
I am using Oracle 11gR2 working on Sample HR database.
This is my 2 cents
+----------------------------------+--------------------------------------------+
+- UNION +- JOIN +
+----------------------------------+--------------------------------------------+
+SELECT 1 AS bah FROM DUAL + SELECT * +
+ EMP.DEPTNO + FROM +
+SELECT 2 AS bah FROM DUAL; + (SELECT 1 AS bah from dual) foo +
+ + JOIN +
+ + (SELECT 2 AS bah from dual) bar +
+ + ON 1=1; +
+----------------------------------+--------------------------------------------+
+- RESULTS +
+----------------------------------+--------------------------------------------+
+This gives everything in vertical + This gives everything in horizontal +
+ BAH + BAH BAH +
+ 1 + 1 2 +
+ 2 + +
+----------------------------------+--------------------------------------------+
+- OBSERVATIONS +
+----------------------------------+--------------------------------------------+
+ UNION puts lines from queries + JOIN makes a Cartesian product +
+ after each other + and subsets it +
+ + +
+ UNION combines the results of + JOIN can retrieve data from two or +
+ two or more queries into a single+ more tables based on logical relationships +
+ result set that includes all the + between the tables. Joins indicate how SQL +
+ rows that belong to all queries + should use data from one table to select +
+ in the union. + the rows in another table. +
+ + +
+ UNION makes two queries look + JOIN examine two or more tables in +
+ like one. + a single query statement +
+ + +
+ UNION returns the results of two + JOIN relates similar data in different +
+ different queries as a single + tables. +
+ recordset. + +
+ + +
+----------------------------------+--------------------------------------------+
JOIN picks fields from table A and fields from table B and put all of them together, JOIN is "horizontal" for example:
SELECT A.A1, A.A2, A.A3, B.B1, B.B2
FROM A
INNER JOIN B
ON A.A10 = B.B20
which can be written also like:
select A1, A2, A3, B1, B2 from TABLEA, TABLEB
WHERE A10 = B20
result:
Field-A1 | Field-A2 | Field-A3 | Field-B1 | Field-B2 |
...
UNION/UNIONALL:
Difference between the two is that UNION returns only distinct results while UNIONALL returns ALL the results (including duplicates). UNION/UNIONALL combines the results of two selects - but there's a "catch" - the column-names must be exactly the same - this property make UNION "vertical", for example:
Select A1 as X1, A2 as X2 from TABLEA
UNIONALL
Select B1 as X1, B2 as X2 from TABLEB
result:
Field-X1 | Field-X2
A1 | A2
B1 | B2
...
join:
A join is an SQL operation performed to establish a connection between two or more database tables based on matching columns, thereby creating a relationship between the tables. Most complex queries in an SQL database management system involve join commands.
e.g:
SELECT Orders.OrderID, Customers.CustomerName, Orders.OrderDate
FROM Orders
INNER JOIN Customers
ON Orders.CustomerID=Customers.CustomerID;
The UNION operator is used to combine the result-set of two or more SELECT statements.
Notice that each SELECT statement within the UNION must have the same number of columns. The columns must also have similar data types. Also, the columns in each SELECT statement must be in the same order
syntax:
SELECT column_name(s) FROM table1
UNION ALL
SELECT column_name(s) FROM table2;

Consolidating results on one row SQL

I would like to consolidate a one to many relationship that outputs on different rows to a single row.
(select rate_value1
FROM xgenca_enquiry_event
INNER JOIN xgenca_enquiry_iso_code_translation
ON
xgenca_enquiry_event_rate.rate_code_id
= xgenca_enquiry_iso_code_translation.id
where xgenca_enquiry_event_rate.event_id = xgenca_enquiry_event.id
and ISO_code = 'PDIV') as PDIVrate,
(select rate_value1
FROM xgenca_enquiry_event
INNER JOIN xgenca_enquiry_iso_code_translation
ON
xgenca_enquiry_event_rate.rate_code_id
= xgenca_enquiry_iso_code_translation.id
where xgenca_enquiry_event_rate.event_id = xgenca_enquiry_event.id
and ISO_code = 'TAXR') as TAXrate
PDIVrate TAXrate
NULL 10.0000000
0.0059120 NULL
I would like the results on one row. Any help would be greatly appreciated.
Thanks.
You can use an aggregate function to perform this:
select
max(case when ISO_code = 'PDIV' then rate_value1 end) PDIVRate,
max(case when ISO_code = 'TAXR' then rate_value1 end) TAXRate
FROM xgenca_enquiry_event_rate r
INNER JOIN xgenca_enquiry_iso_code_translation t
ON r.rate_code_id = t.id
INNER JOIN xgenca_enquiry_event e
ON r.event_id = e.id
It looks like you are joining three tables are are identical in the queries. This consolidates this into a single query using joins.
Look here:
Can I Comma Delimit Multiple Rows Into One Column?
Simulate Oracle's LISTAGG() in SQL Server using STUFF:
SELECT Column1,
stuff((
SELECT ', ' + Column2
FROM tableName as t1
where t1.Column1 = t2.Column1
FOR XML PATH('')
), 1, 2, '')
FROM tableName as t2
GROUP BY Column1
/
Copied from here: https://github.com/jOOQ/jOOQ/issues/1277

SQLite inner join - update using values from another table

This is quite easy and has been asked multiple times but I can't get it to work.
The SQL query I think should work is:
UPDATE table2
SET dst.a = dst.a + src.a,
dst.b = dst.b + src.b,
dst.c = dst.c + src.c,
dst.d = dst.d + src.d,
dst.e = dst.e + src.e
FROM table2 AS dst
INNER JOIN table1 AS src
ON dst.f = src.f
Using the update statement it is not possible because in sqlite joins in an update statement are not supported. See docs:
update statement
If you only wanted to update a single column to a static value, you could use a subquery in the update statement correctly. See this example: How do I make an UPDATE while joining tables on SQLite?
Now in your example, making an assumption that there is a unique key on "column f" - a workaround/solution I have come up with is using the replace statement:
replace into table2
(a, b, c, d, e, f, g)
select src.a, src.b, src.c, src.d, src.e, dest.f, dest.g
from table1 src
inner join table2 dest on src.f = dest.f
I also added an extra column to table2 "column g" to show how you'd "update" only some of the columns with this method.
One other thing to be cautious about is if you use "PRAGMA foreign_keys = ON;" it's possible to have issues with this as the row is effectively deleted and inserted.
I came up with an alternative technique using a TRIGGER and "reversing" the direction of the update, albeit at the cost of a dummy field in the source table.
In general terms, you have a Master table and an Updates table. You want to update some/all fields of records in Master from the corresponding fields in Updates linked by a key field Key.
Instead of UPDATE Master SET ... FROM Master INNER JOIN Updates ON Mater.Key = Updates.Key you do the following:
Add a dummy field TriggerField to the Updates table to act as the focus of the trigger.
Create a trigger on this field:
CREATE TRIGGER UpdateTrigger AFTER UPDATE OF TriggerField ON Updates
BEGIN
UPDATE Master SET
Field1 = OLD.Field1,
Field2 = OLD.Field2,
...
WHERE Master.Key = OLD.Key
END;
Launch the update process with the following:
UPDATE Updates SET TriggerField = NULL ;
Notes
The dummy field is merely an anchor for the trigger so that any other UPDATE Updates SET ... won't trigger the update into Master. If you only ever INSERT into Updates then you don't need it (and can remove the OF TriggerField clause when creating the trigger).
From some rough-and-ready timings, this seems to work about the same speed as REPLACE INTO but avoids the feels-slightly-wrong technique of removing and adding rows. It is also simpler if you are only updating a few fields in Master as you only list the ones you want to change.
It is orders of magnitude faster than the other alternative I've seen to UPDATE ... FROM which is:
UPDATE Master SET
Field1 = ( SELECT Field1 FROM Updates WHERE Mater.Key = Updates.Key ),
Field1 = ( SELECT Field1 FROM Updates WHERE Mater.Key = Updates.Key ),
...
;
Updating six fields over 1700 records was roughly 0.05s for Tony and my methods but 2.50s for the UPDATE ... ( SELECT... ) method.
AFTER UPDATE triggers on Master seem to fire as expected.
As Tony says, the solution is the replace into way but you can use the sqlite hidden field rowid to simulate full update with join like:
replace into table2
(rowid,a, b, c, d, e, f, g)
select dest.rowid,src.a, src.b, src.c, src.d, src.e, dest.f, dest.g
from table1 src
inner join table2 dest on src.f = dest.f
With this you recreate full rows if you don't have primary key for the replace or as standard method to do the updates with joins.
SQLITE does not support UPDATE with INNER JOIN nor do several other DB's. Inner Joins are nice and simple however it can be accomplished using just a UPDATE and a subquery select. By using a where clause and the 'IN' with a subquery and a additional subquery for the 'SET' the same result can always be accomplished. Below is how it's done.
UPDATE table2
SET a = a + (select a from table1 where table1.f = table2.f),
b = b + (select b from table1 where table1.f = table2.f),
c = c + (select c from table1 where table1.f = table2.f),
d = d + (select d from table1 where table1.f = table2.f),
e = e + (select e from table1 where table1.f = table2.f)
WHERE RowId IN (Select table2.RowId from table1 where table1.f = table2.f)
Use below query:
UPDATE table2
SET a = Z.a,
b = Z.b,
c = Z.c,
d = Z.d,
e = Z.e
FROM (SELECT dst.id,
dst.a + src.a AS a,
dst.b + src.b AS b,
dst.c + src.c AS c,
dst.d + src.d AS d,
dst.e + src.e AS e
FROM table2 AS dst
INNER JOIN table1 AS src ON dst.f = src.f
)Z
WHERE table2.id = z.id