SQL Server using IIF resulted AS column in another IIF [duplicate] - sql

This question already has answers here:
Possible to store value of one select column and use it for the next one?
(4 answers)
Using alias in query and using it
(6 answers)
Why can't I use column aliases in the next SELECT expression?
(4 answers)
Closed 9 months ago.
on SQL Server 2012+ I am attempting to use IIF resulted column into another IIF as shown in SQL query below but it is gives me error invalid column. Count table has columns CountId and CountedQty,
SELECT CountId, IIF(CountId<5, 3,2) as MyGroup, IIF([MyGroup]<5, 3,2) as GName FROM Count
Error shown for this query execution is Invalid column name 'MyGroup' if there any way to use IIF resulted column into another IIF in same query
similarly for following query it shows invalid column names errors
SELECT
Count.StockCountId,
Count.CountedQty,
IIf(Count.CountedQty > 0, 1, IIf(Count.CountedQty = 0, 3, 2)) AS MyGroup,
IIf([MyGroup] = 1, "Additional products counted", IIf([MyGroup] =2, "Insufficient products counted", "Matched Count")) AS GName
FROM Count
it returns following errors
Invalid column name 'MyGroup'.
Invalid column name 'Additional products counted'.
Invalid column name 'MyGroup'.
Invalid column name 'Insufficient products counted'.
Invalid column name 'Matched Count'.
what changes are needed to use IIF resulted columns into above query to resolve errors and get intended output

You cannot reference a column alias like that, at the time query execution reaches select it does not yet exist.
You can use a derived table or CTE and then reference the column in an outer query, you can repeat the expression, or in SQL Server you could use apply.
Your logic seems a little odd however as you'll always return 3 since MyGroup is always < 5 in this example.
select CountId, Iif(MyGroup < 5, 3, 2) as GName
from [Count]
cross apply(values(Iif(CountId < 5, 3, 2)))c(MyGroup);

Related

SUBSTRING() function behaving differently in SELECT and WHERE clause? [duplicate]

This question already has an answer here:
Why is it that a change in query plan suddenly seems to break a query
(1 answer)
Closed 4 months ago.
This post was edited and submitted for review 4 months ago and failed to reopen the post:
Original close reason(s) were not resolved
I have a table with the following column:
server
SLQ-ABCD-001
SLQ-ABCA-002
SLP-DBMSA-003
SLD-ABC-004
SLS-123456-005
I would like to be able to filter the rows based on a substring of this column, specifically, the string between those hyphens; there will always be three characters before the first hyphen and three characters after the second hyphen.
Here's what I have tried:
AND substring(server, 5, (len(server)-8)) in ('ABC', 'DBMSA')
AND substring(server, charindex('-', server)+1,(charindex('-',server, charindex('-', server)+1)-(charindex('-', server)+1))) in ('ABC', 'DBMSA')
Both of these work perfectly fine (expected substrings obtained) when used in the SELECT clause but give the error below
Invalid length parameter passed to the LEFT or SUBSTRING function.
I am not able to use the more simpler way, AND server like '%ABC%' as I have more than one combination of characters I'm looking for and also, because that comma separated list will be dynamically parsed in that query for this use case.
Is there any way this type of filter can be achieved in SQL Server?
EDIT
After #DaleK helped me realize that the issue might be I might have some bad data (server names with length < 8) and that I might have missed them when I tested the expression in the SELECT clause since I might have some other filters in my WHERE clause, here's how I had managed to get around that
SELECT *
from
(SELECT *
from my_original_table
where
--all my other filters that helped me eliminate the bad data
) my_filtered_table
where substring(server, 5, (len(server)-8)) in ('ABC', 'DBMSA');
As for the "question being duplicate" part, I think the error in that question is encountered in SELECT statement where as in my case, the expression worked fine in the SELECT statement and only errored when used in the WHERE clause.
For solution, the one provided by #Isolated seems to work perfectly fine!
One simpler approach you can try is the (often misused) parsename function:
Example being
with sampledata as (
select * from (
values('SLQ-ABCD-001'),('SLQ-ABCA-002'),('SLP-DBMSA-003'),('SLD-ABC-004'),('SLS-123456-005')
)x([server])
)
select [server]
from sampledata
cross apply(values(Replace([server], '-','.')))v(v)
where ParseName(v,2) in ('ABC', 'DBMSA');
No need for substring. You could nest left and right with len such as this:
with my_data as (
select 'SLQ-ABCD-001' as server union all
select 'SLQ-ABCA-002' union all
select 'SLP-DBMSA-003' union all
select 'SLD-ABC-004' union all
select 'SLS-123456-005'
)
select server
from my_data
where left(right(server, len(server) - 4), len(right(server, len(server) - 4))- 4) in ('ABC', 'DBMSA')
server
SLP-DBMSA-003
SLD-ABC-004
And left(right(server, len(server) - 4), len(right(server, len(server) - 4))- 4) works fine in the select clause too.

OracleSQL get substring of variable as new variable

I have a column and I would like to get a new column using only the first two characters. I would have assumed the following should work, but it throws FROM keyword not found where expected error
SELECT *,
SUBSTR(PHONE_NUMBER , 1,2) AS MY_PHONE_NUMBER
FROM PHONE_NOS;
Try it here
Alias the table and use it in the statement:
SELECT p.*,
SUBSTR(p.PHONE_NUMBER, 1, 2) AS MY_PHONE_NUMBER
FROM PHONE_NOS p;

SQL Server : ISNULL not returning a value [duplicate]

This question already has answers here:
How to return default value from SQL query
(8 answers)
Closed 2 years ago.
I'm trying to write a SQL Statement (in Microsoft SQL Server) that will always return a value of 0 if there is nothing to be found.
SELECT
ISNULL([ID], 0) AS ID
FROM
ecdb.dbo.tbl_units
WHERE
([GENESYS_NAME] = 'EDRD');
The statement above returns an empty value (nothing), see screenshot.
Now if I enter a true statement that returns a value (replace 'EDRD' with 'ERD'), it returns a value of 1, which is correct.
The reason why I need it to return a value of zero is that I plan to use this statement as a sub query of a master statement where I need the ID (not the GENESYS_NAME) and my table has set aside 0 to be an unknown entry.
Any help?
If you are expecting only 1 row as result you can use an aggregate function like MAX():
SELECT ISNULL(MAX([ID]), 0) AS ID
FROM ecdb.dbo.tbl_units
WHERE ([GENESYS_NAME]='EDRD');
Another way to do it, which will work also if you expect more than 1 rows in the results is with UNION ALL:
SELECT [ID]
FROM ecdb.dbo.tbl_units
WHERE ([GENESYS_NAME]='EDRD')
UNION ALL
SELECT 0
WHERE NOT EXISTS (
SELECT 1 FROM ecdb.dbo.tbl_units
WHERE ([GENESYS_NAME]='EDRD')
)

How to update column of each row with a substring value of another column?

I am trying to fetch the some value from column 'data_sent' and then updating column 'registry' with this value. But getting the issues.
Query below:
update can_data
set registry = (SELECT cast(SUBSTR(split_part(data_sent,
'registry>', 2), 1, 26) as numeric)
as registry FROM can_data);
SQL error:
ERROR: more than one row returned by a subquery used as an
expression
********** Error **********
ERROR: more than one row returned by a subquery used as an expression
SQL state: 21000
You don't need a subquery. All you need is this:
set registry = cast(SUBSTR(split_part(data_sent,
'registry>', 2), 1, 26) as numeric

How select the min between a SQL value and a fixed number

I have to run this query in SQL that will return the min between a fixed scalar (let's say 7) and the value in the column. I tried:
SELECT from theTable min(theTable.Column , 7) AS Label
I get an error saying that I am using the wrong number of arguments in a function on this expression. I cannot copy/paste because I am using Access.
Try this
SELECT
IIF(theTable.Column < 7, theTable.Column, 7) AS Label
FROM
theTable