Create view from 2 tables with one table precedence with other table (mostly both tables are similar except one col) - sql

Create view from 2 tables with one table precedence with other table (mostly both tables are similar except one col).
Need a view from 2 tables.
Table1 table contains below columns with values:
ValueOne = C11
ValueTwo= C12
ValueThree= C13
Table2 table contains below columns (extra id column compare to table1).
Id = 123
ValueOne = C11
ValueTwo= V12
ValueThree= C13
Table2 is precedence over Table1. When w query with ID, and if Id is not there it has to pick the values from Table1. If the Id is available then it has to pick the values from Table2.
For this I need a view to combine these 2 tables and when we query from view we need to get proper results.
example: 1) Select * from ViewName where ID=123
then in this case I have to get below values (from table2, as the ID exist in the table2):
Id = 123
ValueOne = C11
ValueTwo= V12
ValueThree= C13
2) Select * from ViewName where ID=01
in this case it has to get the below values (Id and other values from Table1,
as ID is not there in Table2:
Id = 01
ValueOne = C11
ValueTwo= C12
ValueThree= C13

You will need to use a join. Something like this should work
CREATE VIEW View_1 AS
select t2.*
from Table2 t2
Union ALL
Select t1.*
from table1 t1
LEFT JOIN Table2 t2 on t1.ID = t2.ID
where t2.ID is NULL
I did not test but this should give you a good start.

Related

How to determine if there is a missing value in joined table

I am trying to find the "users" that are missing a value in a 2nd table with the value of column "A" = 16 and then column "B" = 0.
I am looking for these values because that would give me the ability to run a query adding a row for each user that is missing the row with the values of A = 16 and B = 0.
So here is the relevant structure of the tables that we would be joining on.
There are two tables, table 1 and table 2
Table 1
ID
parent id
table 2
table1_id
A
B
The problem I am running into is that table2 can have records associated with the table1_id but still needing to verify if the table2 if there is not a row with table1_id, A missing value 16 while B is missing value 0.
Here is the current idea I am working off of for the sql query
SELECT
*
FROM
table1
LEFT JOIN
table2 ON table1.id = table2.table1_id
WHERE
table1.id IS NOT NULL
AND table2.id IS NULL;
This will give me all the table1_ids that are missing records from table2 but does however would not pull the rows where there are rows for the table1_id but however does not determine if there are missing rows with the column A with value 16 or Column B = 0.
If you are able to answer that would be greatly appreciated. I just currently cannot think of a way I can logically create a query that would do this.
So, you want all rows from table 1
And you want rows from table 2 that are A=16, B=0
And you want to know where the relationship breaks down between table1 and table2:
SELECT t1.*
FROM
table1 t1
LEFT JOIN
(
SELECT * FROM table2 WHERE A=16 and B=0
) a16b0
ON
t1.id = a16b0.table1_id
WHERE
a16b0.table1_id IS NULL
There are more ways to skin this cat, but this should be fairly understandable in the sense of "join table1 to (just the a16/b0 rows from table2)"
Another form you might get on with uses EXISTS:
SELECT * FROM table1 t1
WHERE NOT EXISTS(
SELECT null FROM table2 t2
WHERE t2.table1_id = t1.id AND t2.A = 16 AND t2.B = 0
)
In english it's "Select all from table 1 where, for any particular t1 row, there does not exist a t2 row that has: a matching id in table1_id, a 16 in a, a 0 in b"
A slightly less popular form (historical performance reasons probably) would be perhaps:
SELECT * FROM table1 t1
WHERE id NOT IN (
SELECT table1_id FROM table2 WHERE A = 16 AND B = 0
)
"select everything from table1 where the row's id is not in the list of IDs that are a16/b0 from table 2" - in essence this forms a "big list of everything we dont want" and then says "get me everything that isn't in the list of don't-wants"
This is the solution.
SELECT
*
FROM
table1
LEFT JOIN
table1.id = table2.table1_id AND table2.A = 16 AND table2.B = 0
WHERE
table2.id IS NULL;
#jon Armstrong, thanks for the help.

Avoid joining same table multiple times

I need help in avoiding joining same table multiple times. Here is my sample query.
Table1 have 3 columns ABC_ID,DEF_ID,XYZ_ID and is associated to table2 on ID column . 3 column values in table1 can be null and If values are present then i need to return associated value from table 2 using different column names as in select statement.
As i am using left join i ended up joining table2 three times with table1 on each type if ID column which is having lot of performance issues. How can i write this in different way to avoid join multiple times. Here is sample data. Any help is appreciated
select
(
CASE
WHEN ( table2.ID = table1.ABC_ID)
THEN table2.ID_VAL
ELSE 'TEST1'
END ) AS "TEST1",
(
CASE
WHEN (table2a.ID = table1.DEF_ID)
THEN table2a.ID_VAL
ELSE 'TEST2'
END ) AS "TEST2",
(
CASE
WHEN (table2b.ID = table1.XYZ_ID)
THEN table2b.ID_VAL
ELSE 'TEST3'
END ) AS "TEST3"
from table1 table1
left join table2 table2 on (table2.ID=table1.ABC_ID)
left join table2 table2a on ( table2a.id=table1.DEF_ID)
left join table2 table2b on ( table2b.id=table1.XYZ_ID)
where table1.Id_NUM='1'
Table1
Id_NUM ABC_ID DEF_ID XYZ_ID
1 12345 456789 32145
2 null 456789 32145
3 12345 null null
Table2
ID ID_VAL
12345 abcded
456789 kjwsddk
321456 wedfgfv
OUTPUT
TEST1 TEST2 TEST3
12345 456789 32145
Your joins are fine, but the query can be simplified:
select coalesce(t2a.ID_VAL, 'TEST1') as test1,
coalesce(t2d.ID_VAL, 'TEST2') as test2,
coalesce(t2x.ID_VAL, 'TEST3') as test3
from table1 t1 left join
table2 t2a
on t2a.ID = t1.ABC_ID left join
table2 t2d
on t2d.id = t1.DEF_ID left join
table2 t2x
on t2x.id = t1.XYZ_ID
where t1.Id_NUM = 1;
Notes:
The table aliases should be meaningful. In this case, the aliases include abbreviations for the column used for the join.
Presumably, id_num is a number, so don't use single quotes for the value.
There is no reason to escape the column names. The double quotes just add query clutter.
The case expressions can be replaced by coalesce(), which is simpler (this is not exactly the same if id_val can be NULL, but I'm guessing that doesn't happen).
There is no reason to avoid joining the table three times. That is what your data model requires, because you have three separate foreign key references.

Deleting duplicates from composite Primary key in SQL server

I am using SQL server 2012.
I have two tables with identical structure. (Say there are four columns - ID, C2, C3, C4)
I want to copy data from Table1 to Table2.
The only difference between the two tables is that Table1 contains the local ID in the 'ID' field and table 2 should have the global ID.
There is another third table that contains this mapping between the localID and the global ID.
(multiple local ID's can be mapped to one Global ID)
Example:
ID 'abcd' in russia can be global ID 123
ID 'cdef' in china can be global ID 123
therefore abcd in russia is basically cdef in china (this mapping is stored in table3)
I want to take the GlobalID from table3 corresponding to the local ID that we have in Table1 and insert them into table2.
Table2 has a primary key constraint defined on the column ID+C2.
The problem is that there are high chance we'll have duplicate data - So we want to insert only distinct combination of ID+C2. (clustered PK)
Can someone please help me with this? Sorry if this is confusing.
I right now have this query, but it doesnt eliminates duplicates when copying data from T1 to T2 and thus I get an error on PK.
INSERT INTO TABLE2
(ID,
C2,
C3,
C4)
SELECT T3.ID,
T1.C2,
T1.C3,
T1.C4
FROM TABLE1 T1
JOIN TABLE3 T3 ON T1.ID = T3.ID
JOIN TABLE2 T2 ON T2.ID = T1.ID
I'm not sure, but I guess you want something like
INSERT INTO Table2 (globalID)
SELECT DISTINCT m.globalID from Mapping m inner join Table1 t
on t.country = m.country and t.localId = m.localID
You can use any select, so alter it for your needs.

how to make a simple query that matches column values to a look-up then matches further columns if no match is found

This is a simplified version of a problem I have. Say I’ve got three variables all of the same type, in three columns of table1, and an id field. They are all codes. Mostly they map to variables (group identifyers say) contained in a look up in table2. I want to write a query that does the following:
For each of my records I want to return the variable in table2 that my matches the code in the first of the three columns in table1. However, if the variable in this column contains a value that does not have a match in table2, I want to try for a match using column2. If that one does not match, use the one in column3.
I want the query result to contain the ID from table1 and the match from table2. If there is no match at all, then I want the query to contain a row with the id and n/a.
In this example there are just two values that match in my lookup. I'm actually mapping across 12 columns with a few hundreds of unique code values and several million rows of data.
Table1
id col1 col2 col3
1 V21 G22 T21
2 E30 W21 S34
3 Y11 U29 Q66
Table2
cat_code class_group
V21 group1
W21 group2
Query result
id class_group
1 group1
2 group2
3 n/a
So here in the desired result the record id 1 gets to match the very first column, and returns the corresponding variable, the second record can't get a match on the first but finds one on the second column and the third records can't match any value in any of the three columns so it throws an n/a.
I'm fairly new to SQL - I'm not sure whether this can be achieved in a simple query or whether it needs a functon.
select t1.id,
coalesce(t21.class_group, t22.class_group, t23.class_group) class_group
from Table1 t1
left join Table2 t21 on t21.cat_code = t1.col1
left join Table2 t22 on t22.cat_code = t1.col2
left join Table2 t23 on t23.cat_code = t1.col3
Just like Joel wrote... but he's quicker than I am :)
SELECT [Id], COALESCE(C1.[class_group], C2.[class_group], C2.[class_group], 'N/A')
FROM Table1 AS T1
LEFT JOIN Table2 AS C1 ON C1.[cat_code] = T1.[col1]
LEFT JOIN Table2 AS C2 ON C2.[cat_code] = T1.[col2]
LEFT JOIN Table2 AS C3 ON C3.[cat_code] = T1.[col3]
http://sqlfiddle.com/#!6/ffb01/3
Try this sql query:
SELECT table1.id, table2.class_group
FROM table1
INNER JOIN table2 ON table1.col1 = table2.cat_code
UNION
SELECT table1.id, table2.class_group
FROM table1
INNER JOIN table2 ON table1.col2 = table2.cat_code
SELECT table1.id, table2.class_group
FROM table1
INNER JOIN table2 ON table1.col3 = table2.cat_code

Compare Every Record from Two Tables

Assuming I have two SQL tables consisting of a single column,
i.e.
Table 1 Table 2
a1 a2
b1 b2
c1 c2
Is there a succinct SQL command to compare each record in one table against each record in the other? (and return true if any record from table 1 matches any record from table 2)
i.e.
if( a1 = a2 OR a1 = b2 OR a1 = c2 OR b1 = a2 OR b1 = b2...)
I want
If any record from table a matches table b (i.e., in a table of ints, they are the same int), return true.
Why not simply
if exists (select 1 from T1 inner join TB on T1.Col = T2.Col)
A full join is well suited to finding differences. To find rows that are missing in either table:
select *
from t1
full join
t2
on t1.col1 = t2.col1
where t1.col1 is null
or t2.col1 is null
This assumes that the single column is unique (i.e. has no duplicate values.)