Most Elegant Way to Populate Nulls from Reference Table - sql

I have two tables like so:
Table 1:
Column 1 Column 2
A 1
B NULL
C 3
D 4
Table 2:
Column 1 Column 2
A 1
B 2
C 3
D 4
I receive the data in table 2 on a time delay, and what I need to do when I receive it is populate the null values in Table 1 with the data in table 2. Is there an elegant way to do this in Standard SQL without making temporary tables or using sub-queries?
Thanks!

Consider using a MERGE statement:
MERGE dataset.table1 AS t1
USING dataset.table2 AS t2
ON t1.column1 = t2.column1
WHEN MATCHED THEN
UPDATE SET t2.column2 = t1.column2
Take a look at the supported actions you can perform; if you want to insert new rows, you can do that using MERGE as well.

You can use the UPDATE statement from the DML (Data Manipulation Language) and update Table 1 in place.
It is not clear from your question how you receive data from Table 2, so I will assume that you have a temporary table called Table2. You will have to JOIN Table1 and Table2 in order to find which rows have NULL values, i.e Table1.Column2 IS NULL. Then update Column2 in those rows using the value in Table2. It should be something like this:
UPDATE Table1
SET Column2 = Table2.Column2
FROM
Table1 LEFT JOIN Table2 USING(Column1)
WHERE
Table1.Column2 IS NULL

Correct use of UPDATE statement would be
UPDATE `project.dataset.table1` a
SET Column_2 = b.Column_2
FROM `project.dataset.table2` b
WHERE a.Column_1 = b.Column_1
AND a.Column_2 IS NULL

Related

SQL Update using data from other tables and foreign keys

I am trying to update a column from table1 based off of data from two other tables.
Table 1 has columns id, columnIWantToUpdate, table2FK, table3FK
Table 2 has columns table2FK, table2_unique_id
Table 3 has columns table3FK, table3_unique_id
So I get table2_unique_id and table3_unique_id as inputs and I want to use the columns table2FK and table3FK to update table 1 based off of the unique_ids I received as input
One method uses filtering in the where clause:
update table1
set columnIWantToUpdate = ?
where exists (select 1
from table2 t2
where t2.table2FK = table1.table2FK
) or
exists (select 1
from table3 t3
where t3.table3FK = table1.table3FK
);
It is not clear if you want and and or for the conditions.

Multiple SET in single UPDATE statement?

I'm working on SQL Server, Oracle, DB2 Database.
Currently, I'm performing the below 2 update statement to update one table.
Update 1:
UPDATE TABLE1
SET COL1=TABLE2.ATTRIBUTE1,
COL2=TABLE2.ATTRIBUTE2,
COL3=TABLE2.ATTRIBUTE3
FROM TABLE1
INNER JOIN TABLE2
ON COL1=TABLE2.PID1
AND COL2=TABLE2.PID2
WHERE ROWNUM<10
Update 2:
UPDATE TABLE1
SET COL1=’123-4567890-1’,
COL2=’0000000000’,
COL3=’CONSTANT FULL NAME’
WHERE NOT EXISTS (SELECT 1 FROM TABLE2 WHERE COL1=TABLE2.PID1)
Update 1, helps to updates the TABLE1 if the values match with Table2 and
Update 2, helps to update the TABLE1 if the values, not match with Table2
Is there any other way to convert two update statement into single UPDATE statement?
NOTE: We can use MERGE also, but MERGE will update if the data matched and will insert if the data not matched.
To have one update, you can use two LEFT JOINs, one for each table join condition. And then, in SET part, you use CASE WHEN ... THEN ... END checking if the PK from related joins IS NULL.
Something like below
UPDATE TABLE1
SET COL1=CASE
WHEN T1.PID1 IS NOT NULL THEN T1.ATTRIBUTE1
WHEN T2.PID1 IS NULL THEN ’123-4567890-1’
ELSE COL1
END,
etc.
FROM TABLE1
LEFT JOIN TABLE2 T1 ON COL1=T1.PID1 AND COL2=T1.PID2 AND ROWNUM < 10
LEFT JOIN TABLE2 T2 ON CEDULA=T2.PID1
WHERE T2.PID1 IS NULL OR T1.PID1 IS NOT NULL
However, having one UPDATE statement doesn't mean it will be faster - check the query plan and actual performance.

Trying to Merge data from one table to another

Trying to do a process where I have a table that is existing. This is table A
I have staging table which I have uploaded the data. This is table B.
Table A already contains data in there apart from some data which i need added from table B to Table A.
So Table B has a extra column which I need it to match with the data already existing in Table A.
So layout currently in Table A is:
Column 1 Column 2 Column 3
AB
ABC
Layout in Table B is:
Column 1 Column 2 Column 3
ABC Yellow Test1
AB Blue Test2
So I need these columns 2 and 3 moved to table A from Table B, so they match correctly with the data that is already in column 1.
Tried my best to explain and english is my 2nd language, so i apologise for any mistakes. Anyway know what best way to go with this, would it be a merge?
Thanks
Update TableA
Set TableA.Column2=B.Column2,
TableA.Column3=B.Column3
From TableA A
Inner Join TableB B ON B.Column1=A.Column1
Use Left Outer join to merge data
SELECT TableA.clomun1,
Tableb.column2.tableb.column3
FROM tableA
LEFT JOIN tableB
ON table1.column1 = table2.column1;
Following query is working fine in MySQL , try it out :
update TableA as a inner join TableB as b on a.Column1=b.Column1
set a.Column2 = b.Column2 , a.Column3=b.Column3
where a.Column1=b.Column1;
And for Oracle use this one :
update TableA
set TableA.Column2 =
(select TableB.Column2 from TableB where TableA.Column1=TableB.Column1),
TableA.Column3 =
(select TableB.Column3 from TableB where TableA.Column1=TableB.Column1);
MERGE INTO TableA
USING (SELECT Column1, COlumn2, Column3
FROM TableB) Q
ON (TableA.Column1=TableB.Column1)
WHEN MATCHED THEN UPDATE SET TableA.Column2=Q.Column2
, TableA.Column3=Q.Column3;
This works fine in Oracle. You can also insert records that are not in Table A adding
WHEN NOT MATCHED THEN INSERT (Column1, Column2, Column3)
VALUES (Q.Column1, Q.Column2, Q.Column3)

SELECT clause: Optional Columns?

I want to run a single query on my MYSQL database. The table I am searching has a file_type field that will be one of three values (1,2,3). Depending what these values are I want to look for different information from the database.
So for example if the 'file_type' field is 1 or 2 then I want to SELECT fields a,b,c,d
However if I notice that file_type = 3 then I want to SELECT fields a,b,c,d,e,f
Can this be done in a single SELECT statement? like this - ish
my_simple_query = SELECT file_type,a,b,c,d FROM table1
my_new_query = SELECT file_type,a,b,c,d (AND e,f IF file_type = 3) FROM table1
thanks all
---------------------------------- ADDITION -----------------------------------
And how would I do this if e,f were stored in another table?
my_multitable_query = SELECT file_type,id,a,b,c,d (AND e,f FROM table2 WHERE id=id) FROM table1
get my drift?
No, SQL SELECT statements do not support optional columns.
But you can specify logic to only return values based on criteria, otherwise they would be null:
SELECT a,b,c,d,
CASE WHEN file_type = 3 THEN t2.e ELSE NULL END AS e,
CASE WHEN file_type = 3 THEN t2.f ELSE NULL END AS f
FROM TABLE_1 t1
JOIN TABLE_2 t2 ON t2.id = t1.id
You may be happier using a non-relational database such as CouchDB or MongoDB if you need non-relational data.
In SQL, you have to declare all the columns at the time you write the query. All these columns must be present on every row of the result set; the set of columns cannot vary based on the content in each row. This is practically the definition of being a relational database (along with the requirement that each column has the same type on every row).
Regarding your additional question, this may be getting somewhere:
SELECT t1.file_type, t1.a, t1.b, t1.c, t1.d, t2.e, t2.f
FROM table1 t1
LEFT OUTER JOIN table2 ON t1.id=t2.id;
You'll still get columns e and f on every row of the result set, even if they're NULL because there is no match in table2 for a given row in table1.
This leads to you a pattern called Class Table Inheritance.
Not familiar with mysql, but why not using a UNION?
> SELECT file_type,a,b,c,d FROM table1 WHERE file_type in (1,2)
> UNION
> SELECT file_type,a,b,c,d,e,f FROM table1 WHERE file_type = 3

How do I Write a SQL Query With a Condition Involving a Second Table?

Table1
...
LogEntryID *PrimaryKey*
Value
ThresholdID - - - Link to the appropriate threshold being applied to this log entry.
...
Table2
...
ThresholdID *PrimaryKey*
Threshold
...
All fields are integers.
The "..." thingies are there to show that these tables hold a lot more imformation than just this. They are set up this way for a reason, and I can't change it at this point.
I need write a SQL statement to select every record from Table1 where the Value field in that particular log record is less than the Threshold field in the linked record of Table2.
I'm newish to SQL, so I know this is a basic question.
If anyone can show me how this SQL statement would be structured, it would be greatly appreciated.
SELECT T1.*
FROM Table1 T1
JOIN Table2 T2 ON T2.ThresholdID = T1.ThresholdID
WHERE T2.Threshold > T1.Value
SELECT t1.*
FROM dbo.Table1 t1 INNER JOIN dbo.Table2 t2 ON t1.ThresholdID = t2.ThresholdID
WHERE t2.Threshold > t1.Value
SELECT * from table1 t1 join table2 t2 on (t1.thresholdId = t2.thresholdId)
where t1.value < t2.threshold;
SELECT t1.LogEntryID, t1.Value, t1.ThresholdID
FROM Table1 t1
INNER JOIN Table2 t2 ON t1.ThresholdID = t2.ThresholdID
WHERE t1.Value < t2.threshold
SELECT * FROM Table1
JOIN Table2
ON table1.ThresholdID = table2.ThresholdID --(assuming table 2 holds the same value to link them together)
WHERE
value < thresholdvalue
A 'JOIN' connects 2 tables based on the 'ON' clause (which can be multipart, using 'AND' and 'OR')
If you have 3 entries in table 2 which share table1's primary key (a one-to-many association) you will receive 3 rows in your result set.
for the tables below, for example:
Table 1:
Key Value
1 Hi
2 Bye
Table 2:
Table1Key 2nd_word
1 You
1 fellow
1 friend
2 now
this query:
SELECT * FROM Table1
JOIN Table2
on table1.key = table2.table1key
gets this result set:
Key Value Table1Key 2nd_word
1 Hi 1 You
1 Hi 1 fellow
1 Hi 1 friend
2 Bye 2 now
Note that JOIN will only return results when there is a match in the 2nd table, it will not return a result if there is no match. You can LEFT JOIN for that (all fields from the second table will be NULL).
JOINs can also be strung together, the result from the previous JOIN is used in place of the original table.