How to concat columns in SQL? - sql

PostgreSQL 15.0
I want to make a query that concats two different columns into one.
Desired outcome I showed in the exapmle (it's not a real one but it would be useful to understand on this example).
I've used CONCAT but it does't create new column, just concatenation.
How do I get:
id Col1 Col2
1 foo 10
2 bar 42
3 baz 14
to
id NewColumn
1 foo: 10
2 bar: 42
3 baz: 14

create table t (id int, col1 text, col2 int);
insert into t values
(1, 'foo', 10),
(2, 'bar', 42),
(2, 'baz', 14),
(2, null, 14),
(2, 'wow', null);
select id, coalesce(col1, '') || ': ' || coalesce(col2::text, '') AS NewColumn FROM t
check the live demo here
https://www.db-fiddle.com/f/sNANpwdUPdJfUaSQ77MQUM/1
and read docs here https://www.postgresql.org/docs/current/functions-string.html
And do not forget about null values
But if you want to create a really new column in the table as a result of concatenation:
alter table t
add column NewColumn text
GENERATED ALWAYS AS (
coalesce(col1, '') || ': ' || coalesce(col2::text, '')
) STORED;
select id, NewColumn FROM t
Check the live demo here https://www.db-fiddle.com/f/sNANpwdUPdJfUaSQ77MQUM/2
And documentation https://www.postgresql.org/docs/current/ddl-generated-columns.html

You can use below statement,
select id, Col1||': '||Col2 as NewColumn from table_name;
In order to get Col1 and Col2 as well, you can use below,
select id, Col1, Col2, Col1||': '||Col2 as NewColumn from table_name;

SELECT Name, CONCAT(col1, " ", col2) AS NewColumn FROM Data;
this code concat the 2 column in table, see more info here

Related

WHERE IN clause in temporary columns?

I have a query that creates two temporary columns. Is there a way to check if column 2 value exists in column 1 value?
select x as column1, y as column 2
Result:
column 1 | column 2
x y
w x
how do I check if x exists in column 1 ? Ultimately I only want to get all the values in column 2 that do not have a matching value in column 1, Is this possible?
You can use EXCEPT for this:
Declare #testTable Table (col1 varchar(10), col2 varchar(10));
Insert Into #testTable (col1, col2)
Values ('x', 'y')
, ('w', 'x');
Select col2 From #testTable tt
Except
Select col1 From #testTable tt;

How to get the count of null values for each column in table

I have a table with 20 columns .How do i know if any of the column contains null values. And in case if there are nulls ,how to get count of them.
Use jsonb functions:
create table my_table(id int primary key, val numeric, str text, day date);
insert into my_table values
(1, 10, 'a', '2018-01-01'),
(2, 20, 'b', null),
(3, 30, null, null),
(4, null, null, null);
select key as column, count(*) as null_values
from my_table t
cross join jsonb_each_text(to_jsonb(t))
where value is null
group by key;
column | null_values
--------+-------------
val | 1
str | 2
day | 3
(3 rows)
Working example in rextester.
This Query should Create a query to do that:
SELECT 'SELECT ' || string_agg('count(' || quote_ident(attname) || ') as '||attname||'_not_null_count, count(case when ' || quote_ident(attname) || ' is null then 1 end) as '||attname||'_null_count', ', ')
|| ' FROM ' || attrelid::regclass
FROM pg_attribute
WHERE attrelid = 'myTable'::regclass --> Change myTable to your table name
AND attnum >= 1 -- exclude tableoid & friends (neg. attnum)
AND attisdropped is FALSE -- exclude deleted columns
GROUP BY attrelid;
You can after that transpose columns to rows on excel.
count(nmuloc) only counts rows where the column nmuloc IS NOT NULL. count(*) counts all rows, regardless of anything being NULL or not. So the difference of them is the count of rows where nmuloc IS NULL.
SELECT count(*) - count(nmuloc1) count_of_nulls_in_nmuloc1,
...
count(*) - count(nmuloc20) count_of_nulls_in_nmuloc20
FROM elbat;
You can see that in all_tab_cols, once the table is analyzed or gathered stats on that table.
select COLUMN_NAME, NUM_NULLS from all_tab_cols where table_name = 'tablename'
You can have sql query to get that details like below -
select 'col1Name', count(col1Name) from table where col1Name is null
union
select 'col2Name', count(col2Name) from table where col2Name is null
union ...
select 'col20Name', count(col20Name) from table where col20Name is null
If it is oracle, then you can write some dynamic SQL in stored procedure as well.

SQL - Concat in where clause with IN

I'm trying use IN to query multiple columns. If I use "=", I return rows (see example) but I would like to query multiple.
need query table to return rows A12345 and B98765 but not C00000
column1 | column2
A 12345
B 98765
C 00000
This works
SELECT *
FROM TABLE
WHERE (column1,column2) = ('A',12345)
This does not work.
SELECT *
FROM TABLE
WHERE (column1,column2) IN (('A',12345),('B',98765))
Here is error:
Error: SQL0104N An unexpected token "," was found following ",". Expected tokens may include: "AT MICROSECONDS MICROSECOND SECONDS SECOND MINUTES MINUTE HOURS". SQLSTATE=42601
(State:42601, Native Code: FFFFFF98)
I've tried several variations of parenthesis, commas's, etc and can't get it to work. Is it possible to do this and if so can you provide the syntax.
thanks
DB2 9.7 onwards:
SELECT *
FROM TABLE
WHERE (column1, column2) IN (VALUES ('A', 12345), ('B', 98765))
One solution is to use a temp table:
create table #tmp
(
col1 varchar(2),
col2 int
);
insert into #tmp (col1, col2)
values ('A', 12345), ('B', 98765)
SELECT t.* FROM TABLE t
JOIN #tmp ON #tmp.col1 = t.column1 and #tmp.col2 = t.column2
You haven't stated your RDBMS, but have you tried:
SELECT * FROM TABLE
WHERE (column1, column2) IN ('A', 12345)
OR (column1, column2) IN ('B', 98765)
Depending on your data, this might be workable:
SELECT *
FROM TABLE T
JOIN (
SELECT 'A' COL1, 12345 COL2
UNION ALL
SELECT 'B', 98765
UNION ALL
SELECT 'C', 44365) AS Matches
ON T.column1 = Matches.COL1
AND T.column2 = Matches.COL2
This turned out to be easy and should have known this.
SELECT *
FROM TABLE
WHERE CONCAT(column1, column2) IN ('A12345','B98765')

Change row value to column in SQL

I have table in sql i want to change fieldColumnName as a column and fieldValue as a row.
this is my table image
As per your question, You want to alter table (change column name as well as data type)
ALTER TABLE tablename
CHANGE `fieldColumnName` `column` VARCHAR(255),
CHANGE `fieldValue` `row` VARCHAR(255)
In above query you change datatype as you wish.
If you know all the possible values in the fieldColumnName column then you could use pivot like this:
declare #data table(fieldValue varchar(50), fieldColumnName varchar(50))
INSERT INTO #data
SELECT '1 - value', 'col1'
UNION
SELECT '2 - value', 'col2'
UNION
SELECT NULL, 'col6'
select *
from #data
select col1, col2, col3
from
(
select fieldValue, fieldColumnName
from #data
) d
pivot
(
max(fieldValue)
for fieldColumnName in (col1, col2, col3)
) piv;

Query to display output horizontally

I need to display a query output in a horizontal manner. I have some example data
create table TestTable (id number, name varchar2(10))
insert into TestTable values (1, 'John')
insert into TestTable values (2, 'Mckensy')
insert into TestTable values (3, 'Valneech')
insert into TestTable values (4, 'Zeebra')
commit
select * from TestTable
This gets the output in a vertical view.
ID Name
==========
1 John
2 Mckensy
3 Valneech
4 Zeebra
However, I need to display it horizontally.
ID 1 2 3 4
Name John Mckensy Valneech Zeebra
How can one do this?
To pivot, you should use the pivot clause of the select statement:
select *
from testtable
pivot ( max(name)
for id in (1,2,3,4)
)
This is not particularly pretty to do in SQL, so you should consider carefully whether this is what you want to do. I normally use Oracle Base for pivoting examples but there are many out there.
Here's a little SQL Fiddle to demonstrate.
Maybe it will help you:
select 'id', LISTAGG(id, ' ') WITHIN GROUP (ORDER BY name)
from testtable
union
select 'name', LISTAGG(name, ' ') WITHIN GROUP (ORDER BY name)
from testtable
EDIT:
or with pivot:
create table TestTable2 (id varchar2(30), name varchar2(10));
insert into TestTable2 values ('id', 'name');
insert into TestTable2
select cast(id as varchar2(30)) as id , name
from testtable
select *
from testtable2
pivot ( max(name)
for id in ('id',1,2,3,4)
)
PIVOT operator is what you are looking for.