SQL Create dynamic column - sql

I am seeking some help to build an SQL to obtain certain results.
Below are two tables.
Table 1
Col1 | Col2 | Col3 | Col4
----------------------------------------
TESTPC01 | 14/08/2014 | ABCD | CXYZ
TESTPC02 | 14/08/2014 | EFGH | IJKL
Table2
COl1 | Col2 | Col3 | Col4
----------------------------------------
TESTPC01 | 14/08/2014 | ENT | DOC
RESULT
COl1 | Col2 | Col3 | Col4 | Col5 | Col6
-------------------------------------------------------
TESTPC01 | 14/08/2014 | ENT | DOC | ABCD | YES |
TESTPC02 | 14/08/2014 | EFGH | NULL | NULL | NO |
Yes only when there is data for that particular Col3 value is populated in the Table 2 for that specific matching Table1.Col1 = Table2.Col1.
If above condition fails then NO
I could build the SQL using simple select statements but no able to achieve to create the col6 dynamically.
Can any one please guide me how to achieve this?

You want a left outer join with a conditional expression:
select t2.col1, t2.col2, t2.col3,
(case when t1.col1 is not null then t2.col4 end) as col4
t1.col3 as col5,
(case when t1.col1 is null then 'Yes' else 'No' end) as col6
from table2 t2 left join
table1 t1
on t2.col1 = t1.col1 and t2.col2 = t1.col1;
It is unclear to me why col4 would be NULL when there is no match. Usually, you would keep all values from the first table. However, that is how you have specified the results.

Related

Insert into table, in 2 phases

I have two tables: table1 and table2 (The tables are almost identical, table2 has an extra field. 30 columns in table1, and 31 columns in table2. the extra column is a key).
I also have a procedure, which gets a number at first. If the number is above 10, I want to isnert the row in all the 30 columns from table1 to table2. Otherwise, I want to insert columns 1 to 20 (from table1), and insert columns 20-30 multiplied by 30. I have created two different "INSERT INTO TABLE" for each situation (above/under 10), but I belive there is more efficient way, since the first 20 rows should be the same in every case. I thought to insert first the first 20 rows, and after enter "IF" statement and then 'insert' according to the given parameter the remain columns. But ofcourse I'm getting two rows instead of one.
what is the solution, so I will insert all the data into one row?
Here is an example with 10 columns (instead of 30). In this example, if the paramter is above 10, we'll insert the row as is into table2. otherwise, we will insert col1-col7, and multiply col8-col10.
parameter = 15
table1
Col1 | Col2 | Col3 | Col4 | Col5 | Col6 | Col7 | Col8 | Col9 |Col10 |
======+======+======+======+======+======+======+======+======+======+
1 | 1 | 1 | 2 | 2 | 2 | 2 | 5 | 5 | 5 |
table2 (Identical to table 1, because the parameter > 10 )
Col1 | Col2 | Col3 | Col4 | Col5 | Col6 | Col7 | Col8 | Col9 |Col10 |
======+======+======+======+======+======+======+======+======+======+
1 | 1 | 1 | 2 | 2 | 2 | 2 | 5 | 5 | 5 |
If the parameter was parameter = 3 , then table two was:
table2 (columns 8-10 multiplied)
Col1 | Col2 | Col3 | Col4 | Col5 | Col6 | Col7 | Col8 | Col9 |Col10 |
======+======+======+======+======+======+======+======+======+======+
1 | 1 | 1 | 2 | 2 | 2 | 2 | 150 | 150 | 150 |
A template to my code:
if #Parameter >10
begin
INSERT INTO Table1
(Col1
,Col2
,Col3
...
,Col29
,Col30)
SELECT
Col1
,Col2
,Col3
...
,Col29
,Col30
FROM ...
wHERE ...
end
else
begin
INSERT INTO Table1
(Col1
,Col2
,Col3
...
,Col29
,Col30)
SELECT
Col1
,Col2
,Col3
...
,Col29
,Col30
FROM ...
wHERE ...
end
Right now I have more then 120 lines, when 2/3 from them are duplicated.
How can I make it more efficient?
As far as I could your problem you could use,INSERT ALL COMMAND
FOR eg:-
INSERT ALL
WHEN number>10 THEN
INTO table1 VALUES(col1,col2,col3)
INTO table1 VALUES(col1,col2,col3)
WHEN number<10
INTO table1 VALUES(col1,col2,col3)
INTO table1 VALUES(col1,col2,col3)
select * from dual
use condition as per your requirement

sql table comparisons - postgres

I have two tables with some columns being the same:
TABLE A
| Col1 | Col2 | Col3 |
+------+------+------+
| 1 | aa | ccc |
| 2 | null | ccc |
| null | bb | null |
TABLE B
|Col1 | Col2 | Col3| Col4 |
+------+-------+-----+------+
| 1 | aa | ccc | aaaa |
| 2 | null | ccc | cccc |
| null | bb | null | sss |
| 4 | bb | null | ddd |
I'd like to return the following:
|Col1 | Col2 | Col3| Col4 |
+------+-------+-----+------+
| 4 | bb | null | ddd |
How do I check what rows from table B are in table A and also return Col4 (from table B) where they match in the query.
I was using EXCEPT which worked great but now I need to have the outputs of Col4 in the returned query results.
Thanks.
Something like this?
SELECT Col1, Col2, Col3, Col4
FROM TableB
WHERE NOT EXISTS (
SELECT 1
FROM TableA
WHERE TableA.Col1 IS NOT DISTINCT FROM TableB.Col1
AND TableA.Col2 IS NOT DISTINCT FROM TableB.Col2
AND TableA.Col3 IS NOT DISTINCT FROM TableB.Col3
)
(Using IS NOT DISTINCT FROM to say that columns with null are equal to each other.)
The answer to your question is very easy: none of the rows from table 'A' are in table 'B'.
Those are separate tables and they have separate rows.
Now, if you want to find 'a row in table B, that has similar values in columns as a specific row in table A, you may do following:
select a.*,
case when b.ctid is null then 'I AM A VERY SAD PENGUIN AND ROW IN B WAS NOT FOUND :('
else b.col4 end as col4
from table_a a
left join table_b b on
((a.col1 = b.col1 or (a.col1 is null and b.col1 is null)) and
(a.col2 = b.col2 or (a.col2 is null and b.col2 is null)) and
(a.col3 = b.col3 or (a.col3 is null and b.col3 is null))
)
I assume that by 'similar' you would mean "if null appears in columns in both tables, the rows are still similar.
Notice the last insert into table_b i added - you are not guaranteed to find unique values of col4!:
dbfiddle, modified version of VBoka's answer
If you have no duplicates within the b table, then the following handles NULL values rather elegantly:
select col1, col2, col3, max(col4)
from ((select coll, col2, col3, null as col4, 'a' as which
from a
) union all
(select coll, col2, col3, col4, 'b' as which
from b
)
) b
group by col1, col2, col3
having min(which) = 'b';

Join two table and shows with null values

I have two tables:
Table 1
Col | Col2
--------+---------
AA | CC
Table 2
Col | Col2
--------+---------
BB | CC
Result I need
Col1 | Col2 | Col4
--------+----------+---------
AA | CC | null
null | CC | BB
I can't find any relation between two tables so, i would do :
select col as col1, col2, null as col4
from table1 t1
union all
select null, col2, col
from table2 t2;

Issue in joining 2 datasets

I have two datasets like below:
1:
+---------------------------+
| Id | Col1 | Col2 | Col3 |
+---------------------------+
| 1 | abc | 0 | 01/01/2010 |
| 2 | def | 10 | 10/10/2011 |
+---------------------------+
2:
+-------------------------------------------+
| Id | Col4 | Col5 | Col6 |
+-------------------------------------------+
| 1 | abc | 0 | 01/01/2010 |
| 5 | xyz | 12 | 5/6/2013 |
+-------------------------------------------+
Now I want to combine both these into a single dataset which shows something like this:
+----------------------------------------------------------------------+
| ID | Col1 | Col2 | Col3 | Col4 | Col5 | Col6 |
+----------------------------------------------------------------------+
| 1 | abc | 0 | 01/01/2010 | abc | 0 | 01/01/2010 |
| 2 | def | 10 | 10/10/2011 | null | null | null |
| 5 | null | null | null | xyz | 12 | 5/6/2013 |
+----------------------------------------------------------------------+
The issue is not all ids in dataset 1 are in dataset 2 and vice versa. What i need as all data from datasets1 and 2 and only the common from 1 and 2 with 2 transposed with 1 as shown above. I have used pipe as a separator.
An inputs are highly appreciated. i tried everything like full outer join, inner join , CTE etc - nothing is working.
CREATE TABLE #TEMP1 (ID INT, Col1 VARCHAR(100), Col2 INT, Col3 DATETIME)
CREATE TABLE #TEMP2 (ID INT, Col4 VARCHAR(100), Col5 INT, Col6 DATETIME)
INSERT INTO #TEMP1 VALUES (1,'abc',0,'1/1/2010')
INSERT INTO #TEMP1 VALUES (1,'def',0,'1/1/2010')
INSERT INTO #TEMP2 VALUES (1,'abc',0,'1/1/2010')
INSERT INTO #TEMP2 VALUES (1,'def',0,'1/1/2010')
SELECT DISTINCT A.ID,A.Col1,A.Col2,A.Col3,B.Col4,B.Col5,B.Col6
FROM #TEMP1 A
FULL OUTER JOIN #TEMP2 B ON A.ID = B.ID
Thanks.
Try using below SQL :
select t1.Id , Col1 , Col2 , Col3 , Col4 , Col5 , Col6
from temp1 t1 left join temp2 t2
on t1.Id=t2.Id
union
select t2.Id , Col1 , Col2 , Col3 , Col4 , Col5 , Col6
from temp1 t1 right join temp2 t2
on t1.Id=t2.Id
Also, i tried on fiddle for you :
http://sqlfiddle.com/#!2/d60a1e/5

SQL query to group a column and ignore null values

I have a table like:
Col1 Col2 Col3 Col4
1 a
1 b
1 c
2 e
2 f
2 g
I need to write a query which will have the output like this
Col1 Col2 Col3 Col4
1 a b c
2 e f g
I am using oracle 10g
If you only have one value per column, then you might be able to use an aggregate function:
select
col1,
max(col2) col2,
max(col3) col3,
max(col4) col4
from yourtable
group by col1
See SQL Fiddle with Demo
The result is:
| COL1 | COL2 | COL3 | COL4 |
-----------------------------
| 1 | b | a | c |
| 2 | e | f | g |