Concatenate column names in sql select statement if certain condition is met - sql

I have a SQL SELECT statement pulling 4 columns:
SELECT cmm_residence, cmm_packing, cmm_furniture, cmm_overage
These columns are simple no/yes values (0,1). I need an additional column Description to concatenate any 'Yes' values for that row.
For example: if the query returned 'Yes' for cmm_residence and cmm_furniture, the Description column should be cmm_residence,cmm_furniture.

Schema and insert statements:
create table mytable (cmm_residence varchar(5), cmm_packing varchar(5), cmm_furniture varchar(5), cmm_overage varchar(5));
insert into mytable values('yes','no','no','yes');
insert into mytable values('no','no','no','yes');
insert into mytable values('yes','yes','no','yes');
Query:
select cmm_residence, cmm_packing, cmm_furniture, cmm_overage,
concat(case when cmm_residence='yes' then ' cmm_residence ,'end,
case when cmm_packing='yes' then ' cmm_packing ,'end,
case when cmm_furniture='yes' then ' cmm_furniture ,'end,
case when cmm_overage='yes' then ' cmm_overage 'end)Description
from mytable
Output:
cmm_residence
cmm_packing
cmm_furniture
cmm_overage
Description
yes
no
no
yes
cmm_residence , cmm_overage
no
no
no
yes
cmm_overage
yes
yes
no
yes
cmm_residence , cmm_packing , cmm_overage
db<fiddle here

You can use a CASE into your SELECT statement adding whatever logic you need like this:
SELECT cmm_residence, cmm_packing, cmm_furniture, cmm_overage,
CASE
WHEN cmm_residence = 1 THEN 'cmm_residence'
WHEN cmm_packing = 1 THEN 'cmm_packing'
ELSE ''
END As 'Description'
FROM Table
Just add as much cases with logic as you want, take into account this isn't quite performant query.

Related

Selecting column by its number

How to select table's columns using its number? For example:
Select col:1, col:2
From Banks
instead of
Select Id, Name
From Banks
I have problem like this - I have list of selecting queries in database, but first and second columns has different names/aliases:
Id, Name
Name, Description
1 CODE, 'Male' VALUE
...
I want to filter them with a parameter:
Select Id, Name
From Banks
Where lower(Name) like lower(''%' + p_bank_name + '%'')'
So, how can I write this code:
Select col:1, col:2
From Banks
Where lower(col:2) like lower(''%' + p_bank_name + '%'')'
??
Also, I can write sub queries:
Select col:1, col:2
From (
Select Id, Name
From Banks
) r
Where lower(col:2) like lower(''%' + p_bank_name + '%'')'
But, how??
This is not exactly same as what you are trying to do. However, It is almost there. It won't select column by number, however you dont have to specify the explicit column from your real table while writing this query.
As all us suggested, you have to use the dynamic SQL. This is a little idea I created:
create table test1(name1 varchar(10), address1 varchar(10), zipcode1 varchar(10))
insert into test1 values('Test1.1','USA','12344')
insert into test1 values('Test1.2','USA','12344')
insert into test1 values('Test1.3','USA','12344')
insert into test1 values('Test1.4','USA','12344')
create table test2(name2 varchar(10), address2 varchar(10), zipcode2 varchar(10))
insert into test2 values('Test2.1','USA','12344')
insert into test2 values('Test2.2','USA','12344')
insert into test2 values('Test2.3','USA','12344')
insert into test2 values('Test2.4','USA','12344')
You see, the Table name, and the Column name are completely different in both.
Now this sql statement doesn't care about column names :
select * from
(
select '' as T1, '' as T2, '' as T3
union all
select * from test1 --No matter whether it is Id, Name or description
union all
select * from test2 --No matter whether it is Id, Name or description
) as D
where D.T1<>'' -- your other conditions!
Only issue is, since we are using Union, you have to match the number of columns when you specify your empty columns:
select '' as T1, '' as T2, '' as T3, '' as T4, 0 as T5 -- and so on
Here's the output:

How to set row value is 'No' if values is not found in SQL table?

I have one table name called person.
E.g:
Name Address
-------------------------------------
a India
b US
c UK
I would like to check if particular name is exist or not. If not exists I would like to show as 'No'.
E.g:
I tried below query to get result. But 'D' is not found the table. So, I am getting values as empty.
select Name, case when Name in ('a','d','e') Then 'Yes' Else 'No' END As Status from person
Name Status
------------------------------
a Yes
I need output like as below format:
Name Status
-------------------------------------
a Yes
b Yes
c Yes
d No
e No
Can you please help me. How to solve this task?
Please Make use of below code:
DECLARE #Table TABLE (Name NVARCHAR(20), Country NVARCHAR(20))
INSERT INTO #Table VALUES
('a','India'),
('b','US'),
('c','UK')
Create a table variable to store the name fields you need to check:
DECLARE #Temp TABLE (Name NVARCHAR(20))
INSERT INTO #Temp VALUES
('a'),
('d'),
('e')
SELECT
CASE WHEN T.Name IS NULL THEN TE.Name ELSE T.Name END AS Name,
CASE WHEN T.Name IS NULL THEN 'NO' ELSE 'YES' END AS Staus
FROM #Table T FULL JOIN #Temp TE
ON T.Name =TE.Name
OUTPUT:
Name Staus
a YES
b YES
c YES
d NO
e NO

isnull function does not return correct

When I am using isnull it does not return the '' please see below I have original DOB, isnull used, cast as date.
You would need to convert dob to a char/nchar/varchar/nvarchar type to use isnull() or coalesce() like that.
select isnull(convert(varchar(10),dob,120),'')
if you really would like to return an empty string for the date value, you could try this in a new query window. It creates a table to repoduce your requirement of a null date value and then selects the value before dropping the table.
CREATE TABLE dbo.Test
(
Id INT IDENTITY(1,1) NOT NULL
,Date1 DATE NULL
)
INSERT INTO dbo.Test(Date1) VALUES ('01/01/2017')
INSERT INTO dbo.Test(Date1) VALUES ('01/02/2017')
INSERT INTO dbo.Test(Date1) VALUES (NULL)
INSERT INTO dbo.Test(Date1) VALUES ('01/04/2017')
SELECT * FROM dbo.Test
SELECT Date1 = CASE WHEN date1 IS NULL THEN '' ELSE CAST(DATE1 AS VARCHAR(10)) END from dbo.Test
DROP TABLE dbo.Test
go

replace NULL with Blank value or Zero in sql server

I have a temp table and in that one of my column total_amount is of integer type and NOT NULL. While querying data, I received NULL values for total_Amount column.
How ever I used following syntax to remove nulls but some how still NULL values appearing, correct me if I am wrong.
Create table #Temp1
(
issue varchar(100) NOT NULL,
total_amount int NOT NULL
)
This is my query
Case when total_amount = 0 then 0
else isnull(total_amount, 0)
end as total_amount
I am facing issue at my else part.
You can use the COALESCE function to automatically return null values as 0. Syntax is as shown below:
SELECT COALESCE(total_amount, 0) from #Temp1
The coalesce() is the best solution when there are multiple columns [and]/[or] values and you want the first one. However, looking at books on-line, the query optimize converts it to a case statement.
MSDN excerpt
The COALESCE expression is a syntactic shortcut for the CASE expression.
That is, the code COALESCE(expression1,...n) is rewritten by the query optimizer as the following CASE expression:
CASE
WHEN (expression1 IS NOT NULL) THEN expression1
WHEN (expression2 IS NOT NULL) THEN expression2
...
ELSE expressionN
END
With that said, why not a simple ISNULL()? Less code = better solution?
Here is a complete code snippet.
-- drop the test table
drop table #temp1
go
-- create test table
create table #temp1
(
issue varchar(100) NOT NULL,
total_amount int NULL
);
go
-- create test data
insert into #temp1 values
('No nulls here', 12),
('I am a null', NULL);
go
-- isnull works fine
select
isnull(total_amount, 0) as total_amount
from #temp1
Last but not least, how are you getting null values into a NOT NULL column?
I had to change the table definition so that I could setup the test case. When I try to alter the table to NOT NULL, it fails since it does a nullability check.
-- this alter fails
alter table #temp1 alter column total_amount int NOT NULL
You should always return the same type on all case condition:
In the first one you have an character and on the else you have an int.
You can use:
Select convert(varchar(11),isnull(totalamount,0))
or if you want with your solution:
Case when total_amount = 0 then '0'
else convert(varchar(11),isnull(total_amount, 0))
end as total_amount
Try This
SELECT Title from #Movies
SELECT CASE WHEN Title = '' THEN 'No Title' ELSE Title END AS Titile from #Movies
OR
SELECT [Id], [CategoryId], ISNULL(nullif(Title,''),'No data') as Title, [Director], [DateReleased] FROM #Movies
Different ways to replace NULL in sql server
Replacing NULL value using:
1. ISNULL() function
2. COALESCE() function
3. CASE Statement
SELECT Name as EmployeeName, ISNULL(Bonus,0) as EmployeeBonus from tblEmployee
SELECT Name as EmployeeName, COALESCE(Bonus, 0) as EmployeeBonus
FROM tblEmployee
SELECT Name as EmployeeName, CASE WHEN Bonus IS NULL THEN 0
ELSE Bonus END as EmployeeBonus
FROM tblEmployee
Replace Null Values as Empty: ISNULL('Value','')
Replace Null Values as 0: ISNULL('Value',0)

How to allow temporary tables to accept null values

If you create temp tables using "insert into" in SQL Server it uses the first insert to determine whether a column accepts null value or not. if the first insert has null value the column become nullable otherwise it will be non-nullable.
Is there a way to create temp tables using "insert into" to accept null values?
Example
This works without any problem
Select 'one' as a , null as b
into #temp
insert into #temp
Select 'two' as a , 500 as b
However this throws "Cannot insert the value NULL into column 'b'"
Select 'one' as a , 500 as b
into #temp
insert into #temp
Select 'two' as a , null as b
I know I could do create Table or alter column statement but I want to do it without rewriting hundreds of the existing queries.
How about this?
Select CONVERT(varchar(100), 'one') as a , CONVERT(int, 500) as b
into #temp
insert into #temp
Select 'two' as a , null as b
select * from #temp order by 1
I would workaround this by explicitly creating temporary table before first insert.
create table #temp (a varchar(10) not null, b int null)
(Un)fortunately, this question is too popular and appears at the top for Sybase ASE 15.7 as well, so just adding my answer for Sybase here.
For me neither of cast, convert or coalesce worked, but a case statement did (which is what coalesce is, but eh...)
select
a = case when 1 = 0 then null else 'one' end,
b = case when 1 = 0 null else 500 end
into #temp
This is an old question but I had a similar issue where I UNION NULLs to the initial query which may have helped the OP.
Select 'one' as a , 500 as b
into #temp
UNION
SELECT NULL, NULL
insert into #temp
Select 'two' as a , NULL as b
Putting it here so the next time I need to do this and forget how...