Replace Value in Column with Value in Different Column - sql

I have a dataset that looks like this in SQL.
Col1 Col2 Col3
A 4 1
B 5 NULL
C 6 1
D 7 NULL
E 8 NULL
How do I add a new column with the values in Col2 with the values in Col3 if Col3 = 1, or else keep the existing values in Col2.
Final Expected Output:
Col1 Col2 Col3 Col4
A 4 1 1
B 5 NULL 5
C 6 1 1
D 7 NULL 7
E 8 NULL 8
I tried the coalesce function but I don't think that worked:
SELECT
Col1,
Col2,
Col3,
coalesce(Col3, Col2) AS Col4
FROM table1

Your description suggests a case expression :
select . . .
(case when col3 = 1 then col3 else col2 end) as col4
You could also express the above as
select . . .
(case when col3 = 1 then 1 else col2 end) as col4
For the data you provided, coalesce() should also work.

Try this:
SELECT
Col1,
Col2,
Col3,
CASE WHEN Col3 IS NOT NULL THEN Col3 ELSE Col2 END AS Col4
FROM table1

-- this should do what you want
SELECT
Col1,
Col2,
Col3,
CASE WHEN Col3 = 1 THEN Col3 ELSE Col2 END AS NewCOL
FROM table1

Insert into table2
select
Col1,
Col2,
Col3,
(case when col3 = 1 then 1 else col2 end) as col4
FROM table1

Related

Convert rows to column in Oracle with static column header

I am trying to convert below data set into columns, any help in SQL for this.
Data Set
col1
col2
A
1
A
2
A
3
A
4
A
5
Converted Data Set
col1
col2
col3
col4
col5
col6
A
1
2
3
4
5
You can PIVOT:
SELECT *
FROM data_set
PIVOT(
MAX(col2) FOR col2 IN (
1 AS col2,
2 AS col3,
3 AS col4,
4 AS col5,
5 AS col6
)
)
Or, use conditional aggregation:
SELECT col1,
MAX(CASE col2 WHEN 1 THEN col2 END) AS col2,
MAX(CASE col2 WHEN 2 THEN col2 END) AS col3,
MAX(CASE col2 WHEN 3 THEN col2 END) AS col4,
MAX(CASE col2 WHEN 4 THEN col2 END) AS col5,
MAX(CASE col2 WHEN 5 THEN col2 END) AS col6
FROM data_set
GROUP BY col1
Which, for your sample data:
CREATE TABLE data_set (col1, col2) AS
SELECT 'A', 1 FROM DUAL UNION ALL
SELECT 'A', 2 FROM DUAL UNION ALL
SELECT 'A', 3 FROM DUAL UNION ALL
SELECT 'A', 4 FROM DUAL UNION ALL
SELECT 'A', 5 FROM DUAL;
Both output:
COL1
COL2
COL3
COL4
COL5
COL6
A
1
2
3
4
5
db<>fiddle here

Can I change column order in SQL table based on a value that appears in different columns?

I have a table that looks like this:
Column1 | Column2 | Column3| Column4
4 | 3 | 2 | 1
2 | 1
3 | 2 | 1
I want to flip the columns so that 1 always start in column 1 and then the rest of the values follow to the right. Like this:
Column1 | Column2 | Column3 | Column4
1 | 2 | 3 | 4
1 | 2
1 | 2 | 3
This is an example table. The real table is a hierarchy of a company so 1 = CEO and 2 = SVP for example. 1 is always the same name but as the number gets higher (lower in chain of command) the more names that are in that level. I'm hoping for an automated solution that looks for 1, makes that the first column and then populates the columns. I am struggling because the value that 1 represents is in different columns so I can't just change the order of the columns.
I was able to accomplish this using VBA but I would prefer to keep it in SQL.
I don't have any useful code that I have tried so far.
You can use Case expression:
WITH CTE1 AS
(SELECT 4 AS COL1, 3 AS COL2 , 2 AS COL3, 1 AS COL4 FROM DUAL
UNION ALL
SELECT 2, 1, NULL, NULL FROM DUAL
UNION ALL
SELECT 3, 2, 1, NULL FROM DUAL
)
SELECT CASE WHEN COL1 <> 1 THEN 1 ELSE COL1 END AS COL1,
CASE WHEN COL2 <> 2 THEN 2 ELSE COL2 END AS COL2,
CASE WHEN COL3 <> 3 THEN 3 ELSE COL3 END AS COL3,
CASE WHEN COL4 <> 4 THEN 4 ELSE COL4 END AS COL4
FROM CTE1;
You can apply some CASEes checking all possibilities, this is assuming NULLs for missing data:
COALESCE(col4,col3,col2,col1) AS c1,
CASE
WHEN col4 IS NOT NULL THEN col3
WHEN col3 IS NOT NULL THEN col2
WHEN col2 IS NOT NULL THEN col1
END AS c2,
CASE
WHEN col4 IS NOT NULL THEN col2
WHEN col3 IS NOT NULL THEN col1
END AS c3,
CASE
WHEN col4 IS NOT NULL THEN col1
END AS c4
You want to sort the values. A generic SQL solution would use:
select max(case when seqnum = 1 then col end) as col1,
max(case when seqnum = 2 then col end) as col2,
max(case when seqnum = 3 then col end) as col3,
max(case when seqnum = 4 then col end) as col4
from (select col1, col2, col3, col4, col,
row_number() over (order by col) as seqnum
from ((select col1 as col, 1 as which, col1, col2, col3, col4 from t) union all
(select col2 as col, 2 as which, col1, col2, col3, col4 from t) union all
(select col3 as col, 3 as which, col1, col2, col3, col4 from t) union all
(select col4 as col, 4 as which, col1, col2, col3, col4 from t)
) t
where col is not null
) t
group by col1, col2, col3, col4;
This would be simpler in a database that supports lateral joins. And a unique id on each row would also help.

Distinct records based on some columns in SQL

I have a table named myTable in SQL server database. Let`s say the name of columns is like:
col1, col2, col3, col4, col5
There are thousands of records in the table.
I want to select records with no repetition based on only 4 columns.
currently I use the following query:
SELECT DISTINCT col1, col2, col3, col4 FROM myTable
The query does return unique and distinct records, however I need to have col5 in the result too, even thought I do not want to col5 to be considered when I distinct records.
for example, there are three records in the table as follows:
col1 col2 col3 col4 col5
1 2 3 4 5
2 5 6 9 7
1 2 3 4 10
I want the result to be something like this:
col1 col2 col3 col4 col5
1 2 3 4 5
1 2 3 4 10
That will give you the records you like but only col1 to col4:
SELECT col1, col2, col3, col4
FROM myTable
group by col1, col2, col3, col4
having count(*) > 1
If you also need col5 then use
select t1.*
from myTable t1
join
(
SELECT col1, col2, col3, col4
FROM myTable
group by col1, col2, col3, col4
having count(*) > 1
) t2 on t1.col1 = t2.col1
and t1.col2 = t2.col2
and t1.col3 = t2.col3
and t1.col4 = t2.col4
Edit
After you edited your question, this is the answer:
SELECT col1, col2, col3, col4, min(col5) as col5
FROM myTable
group by col1, col2, col3, col4

SQL assigning a value after testing against multiple columns

I have two columns:
INPUT
col1 col2
1 0
1 0
1 0
2 1
2 0
3 0
3 0
3 1
3 1
Let's suppose col1 holds some entity ID number, which is repeated. I'm testing whether this entity ID contains value 1 in col2. So if entity ID has 1 in corresponding col2 then I create another col3 with "NO"/"YES" values or just "0"/"1" accrodingly.
OUTPUT
col1 col3
1 NO
2 YES
3 YES
SELECT Col1, MAX(CASE WHEN col2 = 1 THEN 1 ELSE 0 END) Col3
FROM YourTable
GROUP BY Col1
UPDATED
Well, since the query above doesn't work for you, you can try the following:
SELECT Col1, MAX(Col3) Col3
FROM ( SELECT Col1,
CASE WHEN col2 = 1 THEN 1 ELSE 0 END AS Col3
FROM YourTable) A
GROUP BY Col1
UPDATE table
SET
col3 = DECODE(col2, 1, 'YES', 'NO');
If you want to run this for a given entity id only:
UPDATE table
SET
col3 = DECODE(col2, 1, 'YES', 'NO')
WHERE
col1 = yourid;
If your column 3 does not exist, you'll have to create it before hand anyway:
ALTER TABLE table ADD (col3 NUMBER NOT NULL);
SELECT Col1,
CASE WHEN MAX(Col2) = 1 THEN 'YES' ELSE 'NO' END AS Col3
FROM TableName
GROUP BY Col1
SQLFiddle Demo
SELECT DISTINCT col1,
CASE WHEN EXISTS(SELECT * FROM MyTab WHERE col1 = M.col1 AND col2 = 1)
THEN 'Yes' ELSE 'No' AS col3 FROM MyTab M

How to figure out which column/value the COALESCE operator successfully selected?

I have a table that I wish to find the first non-null value from 3 (and only 3) columns for each ID starting with Col1 then to Col2 then to Col3
Note: Col3 is NEVER NULL
ID Col1 Col2 Col3
------------------------------
1 A B X
2 NULL C X
3 NULL NULL X
4 D NULL X
To get the correct column for each value I use the following SQL Select
SELECT ID,
COALESCE(Col1, Col2, Col3) AS Col
FROM MyTable
which returns the following and works just fine
ID Col
-------------
1 A
2 C
3 X
4 D
What I want is a third column returned indicating which column the coalesce was successful on. The following is the result set that I wish to produce:
ID Col Source
-----------------------
1 A Col1
2 C Col2
3 X Col3
4 D Col1
Perhaps this will work?
SELECT ID,
COALESCE(Col1, Col2, Col3) AS Col,
CASE COALESCE(Col1, Col2, Col3)
WHEN Col1 THEN 'Col1'
WHEN Col2 THEN 'Col2'
WHEN Col3 THEN 'Col3'
ELSE 'Unknown'
END AS Source
FROM MyTable