BigQuery - How to Select new calculated variable? - sql

How can I select a new variable?
Sample:
Select case when X=1 then 'Y'
else 'N' end as FLAG,
case when FLAG='Y' then 1
else 0 end as Y
from [table]

simply use same case for 2nd variable also for example
Select case when X=1 then 'Y' else 'N' end as FLAG,case when X=1 then '1' else '0' end as Y from [table]

As mention by #Salman ansari, you can just reuse the case for this new variable if your condition is the same.
But lets put a situation where you still want to have that case column as an actual column, you can use with:
with case_data as (
Select id,col1,col2,col3,case when X=1 then 'Y'
else 'N' end as FLAG,
from [table]
)
select id,col1,col2,cole,FLAG,case when FLAG='Y' then 1
else 0 end as Y from [case_data]
By doing that you can display your case column as a column which can be use on the outer with select.
You can explore additional information about case and with usage on:
CASE
WITH

I believe there is no solution in BigQuery. but this can be a work-around.
Select *,
case when FLAG='Y' then 1
else 0 end as Y
from (Select *,
case when X=1 then 'Y'
else 'N' end as FLAG
from [table])

Related

SQL to look at multiple conditions and if ANY are invalid, deliver a single 'NotOk' value

Question for the SQL Geeks out there.
I'm trying to set a flag on a table if any of the 3 below conditions return a 'N' value. Basically, if any of the 3 conditions are met, then I need to set a flag on a Control table. I can't figure out quite how to do this, because I'd also like to return a Reason that the Control table will be set to 'N'. This worked fine with one condition but with 3 I'm not sure.
Here's the SQL:
select Reason, TheCount,Dating_OK_to_Proceed
from
(
SELECT 'More than 2 Seasons Are Open' as Reason, COUNT(SEASCLOSED) as TheCount,
case when COUNT(SEASCLOSED) > 2 then 'N' else 'Y' END as Dating_OK_to_Proceed
FROM dbo.DATING
GROUP BY SEASCLOSED
HAVING (SEASCLOSED = 0)
union all
SELECT 'More than 1 Season has Ordering Switched On' as Reason,
COUNT(ORDERON) as TheCount,
case when COUNT(ORDERON) > 1 then 'N' else 'Y' END as Dating_OK_to_Proceed
FROM dbo.DATING
GROUP BY seasclosed, ORDERON
HAVING (ORDERON > 0) and SEASCLOSED = 0
union all
SELECT 'More than 1 Season has Invoicing Switched On' as Reason,
COUNT(INVOICEON) as TheCount,
case when COUNT(INVOICEON) > 1 then 'N' else 'Y' END as Dating_OK_to_Proceed
FROM dbo.DATING
GROUP BY seasclosed, INVOICEON
HAVING (INVOICEON > 0) and SEASCLOSED = 0
) as OkGo
If all 3 conditions return a Y, instead of 3 rows, I want to return a single row with 'Y'.
But if any of the conditions return a 'N' then I want to return a single row with the corresponding reason and the 'N'.
Is this possible?
One way to solve this:
with OkGo as
(
SELECT 'More than 2 Seasons Are Open' as Reason, COUNT(SEASCLOSED) as TheCount,
case when COUNT(SEASCLOSED) > 2 then 'N' else 'Y' END as Dating_OK_to_Proceed
FROM dbo.DATING
GROUP BY SEASCLOSED
HAVING (SEASCLOSED = 0)
union all
SELECT 'More than 1 Season has Ordering Switched On' as Reason,
COUNT(ORDERON) as TheCount,
case when COUNT(ORDERON) > 1 then 'N' else 'Y' END as Dating_OK_to_Proceed
FROM dbo.DATING
GROUP BY seasclosed, ORDERON
HAVING (ORDERON > 0) and SEASCLOSED = 0
union all
SELECT 'More than 1 Season has Invoicing Switched On' as Reason,
COUNT(INVOICEON) as TheCount,
case when COUNT(INVOICEON) > 1 then 'N' else 'Y' END as Dating_OK_to_Proceed
FROM dbo.DATING
GROUP BY seasclosed, INVOICEON
HAVING (INVOICEON > 0) and SEASCLOSED = 0
)
, RankedReasons as
( select Reason, TheCount, Dating_OK_to_Proceed,
-- if there's any 'N' it will be sorted first and gets rank 1,
-- otherwise 1 is assigned to the first 'Y'
row_number()
over (order by Dating_OK_to_Proceed) as rnk
from OkGo
)
select * from RankedReasons
where rnk = 1 --return a single row for 'Y' or one out of multiple 'N's
To get all rows with 'N' you just have to add a final
or Dating_OK_to_Proceed = 'N'

Shorter CASE ISNULL(qry, '')='' THEN 'no' ELSE 'yes' END

Is there a shorter/better way to write this SQL statement?
Edit: the inner sql select statement is a placeholder, the actual statement is more complex.
SELECT
CASE WHEN
ISNULL((SELECT TOP 1 x FROM y), '') = ''
THEN 'No'
ELSE 'Yes'
END AS BooleanValue
It feels very kludgey because it compares the result of the select statement to null, then sets to an empty string if null; just to check if it is an empty string, and set it to what it actually needs to be: a 'yes' or 'no' string.
Here's one way to do it a bit cleaner.
SELECT
CASE WHEN
(SELECT TOP 1 x FROM y) IS NULL
THEN 'No'
ELSE 'Yes'
END AS BooleanValue
This removes one extra command and should have the same output. I just tested it in sql server 2012.
SELECT ISNULL((SELECT TOP 1 'Yes' FROM x), 'No') as Boolean

SQL Server - Case Statement

I'm almost certain you cannot do this within the context of the case statement, and I haven't been able to find any documentation about it, but is it possible to do the following:
SELECT CASE WHEN testValue > 2
THEN testValue(Without Repeating it) ELSE FailValue)
END
FROM Table
A better more thorough example:
Select CASE WHEN (Foo-stuff+bar) > 2
THEN Conditional statement without >2 Else "Fail"
END
FROM TABLE
I am looking for a way to create a select without repeating the conditional query.
EDIT: Due to a poor example on my part, and the lack of answers I was looking for:
testValue = (Table.A / Table.B) * Table.C Table.D
SELECT CASE WHEN testValue > 2
THEN testValue ELSE FailValue)
END
FROM Table
Like so
DECLARE #t INT=1
SELECT CASE
WHEN #t>0 THEN
CASE
WHEN #t=1 THEN 'one'
ELSE 'not one'
END
ELSE 'less than one'
END
EDIT:
After looking more at the question, I think the best option is to create a function that calculates the value. That way, if you end up having multiple places where the calculation needs done, you only have one point to maintain the logic.
The query can be written slightly simpler, like this:
DECLARE #T INT = 2
SELECT CASE
WHEN #T < 1 THEN 'less than one'
WHEN #T = 1 THEN 'one'
ELSE 'greater than one'
END T
I am looking for a way to create a select without repeating the conditional query.
I'm assuming that you don't want to repeat Foo-stuff+bar. You could put your calculation into a derived table:
SELECT CASE WHEN a.TestValue > 2 THEN a.TestValue ELSE 'Fail' END
FROM (SELECT (Foo-stuff+bar) AS TestValue FROM MyTable) AS a
A common table expression would work just as well:
WITH a AS (SELECT (Foo-stuff+bar) AS TestValue FROM MyTable)
SELECT CASE WHEN a.TestValue > 2 THEN a.TestValue ELSE 'Fail' END
FROM a
Also, each part of your switch should return the same datatype, so you may have to cast one or more cases.
We can use case statement Like this
select Name,EmailId,gender=case
when gender='M' then 'F'
when gender='F' then 'M'
end
from [dbo].[Employees]
WE can also it as follow.
select Name,EmailId,case gender
when 'M' then 'F'
when 'F' then 'M'
end
from [dbo].[Employees]

SQL case with different fields to check from same table

I have the following problem:
I have a select statement that includes a case part. Up til there it is easy the problem is that the case includes a check against another field in the same table.
select h.id,
case h.value
when 'P' then 'test'
when '' then 'failed'
when 'D' then 'passed'
else null end
as info,
b.text,
case h.diag
when h.value = '' [or 'failed' not sure tried both and didn't work]
else h.diag end
as diag1, h.date from valuetab h, texttab b where h.id=b.id
I want to have h.diag only to show values when h.value is not failed.
I always get the mistake that the = should be concat.. but that doesn't make sense in my eyes.
Any ideas??
Thats for all your help.
You can also write a case statement with your expression in a different place i.e.
SELECT CASE WHEN X = 1 THEN 'Y' WHEN X = 2 THEN 'Z'
I think what you want to do is something more like this:
SELECT CASE WHEN h.value = '' THEN h.diag end
Use the other form of case statement, which doesn't specify a column you want to look at:
select case
when column1 = 2 then 'Foo'
when other_column = 'blah' then 'Bar'
end
from table
The problem with using case column1 when... is that it implicitly compares column1 to each when clause. You can't then include a comparison to some other column in it.
You are missing a THEN portion of the WHEN clause, and specifying a condition where you could specify a value:
case h.value
when '' THEN NULL
else h.diag end
Ok got it....
after the 2nd case the "h.diag" must be removed....
so it is
case
when h.value = '' then null
else h.diag end
as diag1,

transforming from 'Y' or 'N' to bit

I have a table which has a column called Direct of type char(1). It's values are either 'Y' or 'N' or NULL. I am creating a view and I want the value to be transformed to either 0 or 1 of type bit. Right now it's of type INT. How do I go about doing this?
Following is the code:
CASE WHEN Direct = 'Y' THEN (SELECT 1)
WHEN Direct <> 'Y' THEN (SELECT 0) END AS DirectDebit
EDIT: How can I make sure the column type is of type BIT?
This will get you your bit..
CAST(CASE WHEN Direct = 'Y' THEN 1 ELSE 0 END AS BIT) AS DirectDebit
See if this works:
SELECT CASE WHEN Direct = 'Y' THEN 1 ELSE 0 END FROM YOURTABLE
SELECT CASE Direct
WHEN 'Y' THEN '1'
WHEN 'N' THEN '0'
ELSE '0'
END as DirectDebit
FROM TableName
... should work.