How can I create a select statement for a view and inside of it, convert the datatype of the OverallSat Column from nvarchar(10) to a decimal(10,2) only where the values are not null. Crystal reports is having a difficult time with this column.
Current Statement:
SELECT [BPF_FR_ID]
,[ResolveDate]
,[Organization]
,[AssigneeGroup]
,[Survey_Category]
,[HDATechComp]
,[TechComp]
,[ProfCourt]
,[Timeliness]
,[OverAllSat]
,[KeySent]
,[CheckSave]
,[TicketNumber]
,[Form]
FROM [NotesData].[dbo].[BPF_FinanceReport_tbl]
I am looking to replace the value of [OverAllSat] with something like this...
Select OverAllSat,
Case When IsNumeric(OverAllSat)<>0 THEN
CONVERT(nvarchar(10),CONVERT(decimal(10,2),OverAllSat))
ELSE
OverAllSat
End as OverAllSat
From [NotesData].[dbo].[BPF_FinanceReport_tbl]
Is this possible through a view selection criteria, or does it have to be somewhere else(trigger on insert/update). any Examples are greatly appreciated.
Thank you!
You can use ISNULL()
Select OverAllSat,
Case When IsNumeric(ISNULL(OverAllSat,0)) = 1 THEN
CONVERT(decimal(10,2),OverAllSat)
ELSE
CONVERT(decimal(10,2),ISNULL(OverAllSat,0))
End as OverAllSat1
From [NotesData].[dbo].[BPF_FinanceReport_tbl]
Or if you are really strict about how it has not to be null then you have to add it to your case condition.
Select OverAllSat,
Case
When OverAllSat IS NOT NULL AND IsNumeric(OverAllSat) = 1 THEN
CONVERT(decimal(10,2),OverAllSat)
When OverAllSat IS NOT NULL THEN
CONVERT(decimal(10,2),OverAllSat)
ELSE
0
End as OverAllSat1
From [NotesData].[dbo].[BPF_FinanceReport_tbl]
You'll have to separate that out to two columns. One that is decimal(10,2) and the other that is varchar(10). This sort of formatting task should be left to your presentation layer if possible.
Related
view in snowflake as follows;
CREATE OR REPLACE VIEW A AS(
SELECT tab1.colA,
tab1.colB,
CASE WHEN COALESCE(DATE_ACT_CREATED,'missing')='missing' THEN DATE ('1970-01- 01') ELSE TO_DATE(DATE_ACT_CREATED) END AS ACT_CREATED_DATE
FROM tab1);
Please note that because of some reasons, column DATE_ACT_CREATED was defined as varchar earlier. This view is created fine. But when I try to retrieve records from it;
SELECT * FROM viewA;
I get following error,
Date '' is not recognized
But when I take out the entry; CASE WHEN COALESCE(DATE_ACT_CREATED,'missing')='missing' THEN DATE ('1970-01- 01') ELSE TO_DATE(DATE_ACT_CREATED) END AS ACT_CREATED_DATE the error is gone.
May I know how can I handle this date error issue? Found this link enter link description here, but it couldn't help much.
Help is appreciated.
You get the error because the case when DATE_ACT_CREATED is an empty string is not handled in your CASE condition. So the TO_DATE function couldn't work.
You should try TRY_TO_DATE. If your entry couldn't be casted as a date then it returns null that will be handled with your COALESCE.
CREATE OR REPLACE viewA AS(
SELECT
tab1.colA,
tab1.colB,
COALESCE(TRY_TO_DATE(DATE_ACT_CREATED), DATE('1970-01- 01')) AS ACT_CREATED_DATE
FROM tab1);
Using the following query you will not get the error if the input is ''(Empty string), actual date, NULL keyword, or missing keyword.
CREATE OR REPLACE VIEW A
AS
SELECT COL1, COL2,
CASE WHEN COALESCE(DATE_AT_CREATED, '') = '' THEN DATE('1970-01-02')
ELSE CASE WHEN DATE_AT_CREATED = 'missing' THEN DATE('1970-01-02') ELSE TO_DATE(DATE_AT_CREATED) END
END AS ACT_CREATED_DATE
FROM TAB1;
SELECT * FROM A;
I am inserting data from one table to another so when inserting I got above error mentioned in title
Insert into dbo.source(
title
)
Select
Title from dbi.destination
title in dbo.source table is of INT data type and title in dbo.destination table is of Varchar data type and I have data like abc, efg, etc. in the dbo.destination table.
So how to solve this now or is it possible to convert and insert values?
You can use SQL Server try_cast() function as shown below. Here is the official documentation of TRY_CAST (Transact-SQL).
It Returns a value cast to the specified data type if the cast succeeds; otherwise, returns null.
Syntax
TRY_CAST ( expression AS data_type [ ( length ) ] )
And the implementation in your query.
INSERT INTO dbo.source (title)
SELECT try_cast(Title AS INT)
FROM dbi.destination
Using this solution you need to be sure you have set the column allow null true otherwise it will give error.
If you do not want to set the allow null then you need minor changes in select query as shown below - passing the addition criteria to avoid null values.
Select ... from ... where try_cast(Title AS INT) is not null
You must use isnumeric method of SQL for checking is data numeric or not
CONVERT(INT,
CASE
WHEN IsNumeric(CONVERT(VARCHAR(12), a.value)) = 1 THEN CONVERT(VARCHAR(12),a.value)
ELSE 0 END)
Think about your data types - obviously you cannot have a text string like 'abc' in a column that is defined to hold integers.
It makes no sense to copy a string value into an integer column, so you have to confirm how you want to handle these - do you simply discard them (what is the impact of throwing data away?) or do you replace them with some other value?
If you want to ignore them and use NULL in place then use:
INSERT dbo.Source (Title)
SELECT CASE
WHEN ISNUMERIC(Title) = 1 THEN CAST(Title as INT)
ELSE NULL
END
FROM dbo.Destination
If you want to replace the value then simply change NULL above to the value you want e.g. 0
You can use regex to root out non numeric characters
Insert into dbo.source(
title
)
Select
case when Title not like '%[^0-9]%' then null else cast(Title as int) end as Title
from dbi.destination
Just filter only numeric field from destination table like as below:
Insert into dbo.source(
title
)
Select
Title from dbi.destination
where ISNUMERIC(Title) = 1
This is a very simplified vision of the statement
SELECT
ChangeId,
ColumnName,
BeforeChange,
CASE ColumnName
WHEN 'x' THEN AfterChange ELSE 'dbo.function(Y)'
END AS AfterChange,
AfterChangeUpdateId,
UpdatedBy,
ChangeDate,
ChangeType
FROM
[DEV].[dbo].[tblperson_Audit]
Not sure this is possible but I want to pass the ColumnName value in to the CASE statment to show different results depending upon the value for every row.
The function passes a value for an integer.
Any help would be great thanks
Can you try this? It is assumed that the function returns single value
SELECT ChangeId,
ColumnName,
BeforeChange,
CASE ColumnName WHEN 'x' THEN AfterChange ELSE dbo.function(ColumnName) END AS AfterChange,
AfterChangeUpdateId,
UpdatedBy,
ChangeDate,
ChangeType
FROM [DEV].[dbo].[tblperson_Audit]
Slight syntax error in Madhivanan's solution. It should be:
case when condition() then column1 else column2 end as columnname
So in your example:
CASE WHEN 'x' THEN AfterChange ELSE 'dbo.function(Y)' as AfterChange
SQL Server's conditional syntax always seems so counter-intutive and weird I have to Google it every time...
I have a table that has a column of values that can be rowTypeID = (1,2,3, or null) . I would like to write a query that returns any row that doesn't have a value of 3 in it. In this example I want all NULL rows along with all 1,2 rows I just don't want rows with the value of 3
Set ANSI null ON is currently set for the database.
I'm curious as to why I can't write
select * from myTable where myCol <> 3
This query will not return any rows that have NULL in the myCol column
I have to write
select * from my Table where myCol <> 3 or myCol Is NULL
Do I always have to include the IS NULL or can I set it up so a where clause myCol <>3 will return rows that have Null as value for my Col
I think your approach is fine:
SELECT *
FROM MyTable
WHERE myCol <> 3 OR myCol IS NULL
Since you are asking for alternatives, another way to do it is to make your column NOT NULL and store another (otherwised unused) value in the database instead of NULL - for example -1. Then the expression myCol <> 3 will match your fake-NULL just as it would with any other value.
SELECT *
FROM MyTable
WHERE myCol <> 3
However in general I would recommend not to use this approach. The way you are already doing it is the right way.
Also it might be worth mentioning that several other databases support IS DISTINCT FROM which does exactly what you want:
SELECT *
FROM MyTable
WHERE myCol IS DISTINCT FROM 3
MySQL has the NULL-safe equal which can also be used for this purpose:
SELECT *
FROM MyTable
WHERE NOT myCol <=> 3
Unfortunately SQL Server doesn't yet support either of these syntaxes.
You must handle the NULLs one way or another, since expressions involving NULL evaluate to Unknown. If you want, you could instead do:
select *
from MyTable
where isnull(MyColumn, -1) <> 3
But this involves a magic number (-1), and is arguably less readable than the original test for IS NULL.
Edit: and, as SQLMenace points out, is not SARGable.
Whenever you test for a value all NULLs are omitted – after all, you are testing whether the value in some column passes certain criteria and NULL is not a value.
Do I always have to include the IS NULL or can I set it up so a where clause myCol <>3 will return rows that have Null as value for my Col?
You always, always, always have to include is null.
Because 3 does not equal Not/Applicable and it does not equal Unkown.
because you can't compare NULL to anything else, NULL is not even equal to NULL
DECLARE #i INT
DECLARE #i2 INT
SELECT #i = NULL, #i2 = NULL
IF #i = #i2
PRINT 'equal'
ELSE
PRINT 'not equal'
What is the best way to include an input param in the WHERE clause but exclude it if it is null?
There are a number of ways I believe, but I can't seem to remember then.
Also could I use the COALESCE()? But I think this is only for SELECTing values?
Edit
To clarify, let's say a variable called #code ="1" then my where would be Where type='B' AND code = #code but if #code is null then I only want Where type='B' - notice the missing code = #code.
You can use IsNull
where some_column = IsNull(#yourvariable, 'valueifnull')
EDIT:
What you described in the comment can be done like:
where (#code is null or code = #code)
Here's another approach
SELECT * FROM Thingies WHERE ( #thingId IS NULL OR ThingID = #thingId )
How about
WHERE (Column1 = #Var1 OR #Var1 IS NULL)
AND (Column2 = #Var2 OR #Var2 IS NULL)
I’d like to suggest a solution which I found on another site:
SELECT * FROM Thingies
WHERE ThingID = isnull(#ThingId,ThingID)
With this solution if the user selects null for your parameter then your query will return all the rows as the result.
This question really helped me with a similar issue that had a few of us scratching our heads for a bit. I only write it up in case somebody else tries the same approach and cannot figure out why it does not work.
I was trying to only evaluate a part of a multipart WHERE clause if the #Parameter was not null. I tried to do this as below but always had no rows returned if #Parameter was null.
DECLARE #Parameter int = null;
SELECT * FROM TABLE
WHERE [AlternateID] is not null
AND (#Parameter is not null AND [AlternateID] = #Parameter)
I incorrectly thought that (#Parameter is not null AND [AlternateID] = #Parameter) would simply not form part of the full WHERE clause is #Parameter was null. However it was making the entire WHERE clause return false. The remedy was to add an OR 1=1 as below:
WHERE [AlternateID] is not null
AND (#Parameter is not null AND [AlternateID] = #Parameter OR 1=1)
Of course the approach outlined by Ali (not enough reputation to upvote) solves this more efficiently.
WHERE [AlternateID] is not null
AND [Partner_Customer_ID] = ISNULL(#Parameter, [Partner_Customer_ID])
You can use ISNULL(), or check for nulls explicitly as others have mentioned. This should be OK as long as you have no more than 1 or 2 optional input parameters. But if there are more parameters, this approach would be very inefficient as the indexes you create on those columns won't be used as you would expect. In such a case i would recommend you to use dynamic SQL. Here is an excellent article that explains why http://sqlinthewild.co.za/index.php/2009/03/19/catch-all-queries/
I think this will help
#id
#name
SELECT [Id],[Name] FROM [Person]
WHERE Id = #id and ISNULL(#name, Name)
This will allow you just ignore the Name condition if it is null