Get all permutations of values - into pairs - sql

I have X amount of values being passed into a table via CSV - so I take 99315,99316,99223 and split them out into a single column temp table - each value in the CSV into a single row.
What I need to be able to do is to get every permutation of values in pairs -
so - something like:
Col1 Col2
99315 99316
99315 99223
99316 99315
99316 99223
99223 99315
99223 99316

select t1.col1, t2.col1 col2
from mytable t1
cross join mytable t2
if you want to exclude like values add
where t1.col1 <> t2.col1

A faster way to write this query is to just do
SELECT t1.col1, t2.col1 col2
FROM table1 t1, table2 t2
and then you can add filters with a WHERE as well

Related

Update large amount of rows from other table

Let's say I have Table1 (Id, Row1, Row2) and Table2 (Id, Row1, Row2) with same schema.
In table1 I have data with the same id than in table2 and I want to update Row1 and Row2 for each corresponding Id. But I have a lot of data (around 10 000 000 rows) and it's very slow with a loop.
Is it possible to update all rows faster?
Note: I can't truncate and bulk insert because in table2 I can have data that is not in table1.
Sure. Just join the two tables together, and run an UPDATE over the results of the JOIN, eg:
with q as
(
select t1.id, t1.Col1, t1.Col2, t1.Col3,
t2.Col1 Col1_new, t2.Col2 Col2_new t2.Col3 Col3_new
from Table1 t1
join Table2 t2
on t1.id = t2.id
)
--select * from q
update q set Col1 = Col1_new, Col2 = Col2_new, Col3 = Col3_new

How to write an SQL query that uses wild-card map to do transformation

I have a source table A with a number of columns. I want to do a transformation of the source table to a target table. I would like to have a mapping table with same columns as the source table A and with rows that make up the translations.
Here is an example of the table A:
COL1 COL2 COL3
aktie ja 2
aktie nej 3
obli ja 2
and here is the mapping table
COL1 COL2 COL3 TRANSFORM
aktie ja NULL 3
aktie NULL NULL 4
Now, the idea is to join the source table with the mapping and get the transformed value returned. The use of NULL should serve as a wildcard. So my desired result should be that the first row in table A would match the first row in the mapping table and return the value 3
For the second row - and here is my challenge - I want it to match the second row in the mapping table because it is NOT matched by rows that have a value already (which would result in the transformed value 3) and as the second mapping row has NULL in column two, it should be treated as a wildcard (although taking into account other rows in the mapping table as well).
My first attempt would be something like
select A.*, m.res
from tab1 A
inner join mapping m on t.col1 = isnull(m.col1, t.col1)
and t.col2 = isnull(m.col2, t.col2)
and ...
but the problem is that the isnull(..,..) will match everything and not only return matches except the listed possible values that would result in a different transformation.
I am looking for a generic solution that would Work for any table with any number of columns, not only this particular table-layout mentioned here.
I have been thinking a lot about this and cannot really seem to come up with the solution, so please help :)
Here is one way to do this using a CTE (will work on SQL Server and Oracle)
WITH Map3 as
( -- TRANSFORM WILL BE NULL IF A MATCH WAS NOT MADE
SELECT T1.COL1, T1.COL2, T1.COL3, M.TRANSFORM
FROM Table1 T1
LEFT JOIN Mapping M ON T1.COL1 = M.COL1
AND T1.COL2 = M.COL2
AND T1.COL3 = COALESCE(M.COL3, T1.COL3)
), Map2 as
(
SELECT T1.COL1, T1.COL2, T1.COL3, COALESCE(T1.TRANSFORM,M.TRANSFORM)
FROM Map3 T1
LEFT JOIN Mapping M ON T1.COL1 = M.COL1
AND T1.COL2 = COALESCE(M.COL2, T1.COL2)
AND T1.TRANSFORM IS NULL
)
SELECT *
FROM Map2
I believe it is clear how this works and how to "extend" this to more columns.
If you can't use a CTE this is functionally the same and can be nested as far as you like:
SELECT T1.COL1, T1.COL2, T1.COL3, COALESCE(T1.TRANSFORM,M.TRANSFORM)
FROM (
-- TRANSFORM WILL BE NULL IF A MATCH WAS NOT MADE
SELECT T1.COL1, T1.COL2, T1.COL3, M.TRANSFORM
FROM Table1 T1
LEFT JOIN Mapping M ON T1.COL1 = M.COL1
AND T1.COL2 = M.COL2
AND T1.COL3 = COALESCE(M.COL3, T1.COL3)
) T1
LEFT JOIN Mapping M ON T1.COL1 = M.COL1
AND T1.COL2 = COALESCE(M.COL2, T1.COL2)
AND T1.TRANSFORM IS NULL

SQL - Compare all column's data from two tables efficiently

I have two tables say Table1 and Table2 with same columns and same schema structure.
Now I want to select data from Table1 which is present in Table2. However, when comparing data, I want to compare all the columns present in both these table. Like, entire record in Table1 should be present in Table2. What is the fastest and most efficient way to achieve this in SQL Server 2008? Both the tables contain around 1000-2000 records and these tables will get accessed very frequently.
The intersect operator does just that:
SELECT *
FROM table1
INTERSECT
SELECT *
FROM table2
With an " exists", you have a solution :
select * from Table1 t1 where exists (select 1 from Table2 t2
where t1.col1 = t2.col1
and t1.col2 = t2.col2
and t1.col3 = t2.col3
and ... // check here all columns ...
)
There is however a little problem in this solution in the case of null values, which can only be tested via a "IS NOT NULL" or "IS NULL", hence the complementary solution:
select * from Table1 t1 where exists (select 1 from Table2 t2
where (t1.col1 = t2.col1 or (t1.col1 IS NULL and t2.col1 IS NULL))
and (t1.col2 = t2.col2 or (t1.col2 IS NULL and t2.col2 IS NULL))
and (t1.col3 = t2.col3 or (t1.col3 IS NULL and t2.col3 IS NULL))
and ... // check here all columns ...
)

compare two table values

I have 2 tables table A and table B. In table B we have to check if all the column entered is exactly as in table A, means if a row exists in table B then the same row will be there in table A too. also table A may have rows which are not in table B. if there is a row which is not in table A and is there in table B, an alert should be displayed showing which element is extra in table B.
Can we do this using join? if so what will be the sql code?
this is the best picture about joins i've ever seen :)
You probably want to have a look at the following article
SQL SERVER – Introduction to JOINs – Basic of JOINs
This should give you a very clear understanding of JOINs in Sql.
From there you should be able to find the solution.
As an example, you would have to look at something like
TABLE1
Col1
Col2
Col3
Col4
TABLE2
Col1
Col2
Col3
Col4
--all rows that match
SELECT *
FROM TABLE1 t1 INNER JOIN
TABLE2 t2 ON t1.Col1 = t2.Col1
AND t1.Col2 = t2.Col2
...
AND t1.Col3 = t2.Col3
--rows only in TABLE1
SELECT *
FROM TABLE1 t1 LEFT JOIN
TABLE2 t2 ON t1.Col1 = t2.Col1
AND t1.Col2 = t2.Col2
...
AND t1.Col3 = t2.Col3
WHERE t2.Col1 IS NULL
--rows only in TABLE2
SELECT *
FROM TABLE1 t2 LEFT JOIN
TABLE2 t1 ON t1.Col1 = t2.Col1
AND t1.Col2 = t2.Col2
...
AND t1.Col3 = t2.Col3
WHERE t1.Col1 IS NULL
If you want to compare based on single column, then you can do something like this:
SELECT ID FROM B LEFT JOIN A ON B.ID = A.ID WHERE A.ID IS NULL;
The above query will give you the list of records that are not present in A but in B.
Instead if you want to compare the entire row, you can use the following approach:
SELECT COUNT(*) FROM B;
SELECT COUNT(*) FROM A;
SELECT COUNT(*) FROM (
SELECT * FROM B UNION SELECT * FROM A
)
If all the queries returns the same count then you can assume that both the tables are exactly equal.

Simple T-SQL Join question

I am trying to select a record out of the table1 by joining table2 and using table2 columns in the WHERE statement. Col1 and Col2 in table1 can be stored in col1 of table2. I need to join col1 of table2 with either the value of col1 or col2 in table1
here is the sql statement I created so (pseudo):
SELECT
t1.Col1,
t1.Col2,
t1.Col3,
t1.Col4
FROM
table1 t1
JOIN table2 t2 on t2.Col1 = t1.Col1 or t2.Col1 = t1.Col2
What would be the best way to approach this?
That should be fine. Another way to write the same condition is as follows:
... JOIN table2 t2 on t2.Col1 IN (t1.Col1, t1.Col2)
It shouldn't matter which way you do it in this case. Do what you find more readable.
If I understand your questoion correctly, your SQL query is perfectly fine.