Using the result of a subquery in a CASE expression with T-SQL - tsql

I'm writing a query with some CASE expressions and it outputs helper-data columns which help me determine whether or not a specific action is required. I would like to know if I can somehow use the result of a subquery as the output without having to perform the same query twice (between WHEN (subquery) THEN and as the result after THEN)
The dummy code below describes what I'm after. Can this be done? I'm querying a MS2005 SQL database.
SELECT 'Hello StackOverflow'
,'Thanks for reading this question'
,CASE
WHEN
(
SELECT count(*)
FROM sometable
WHERE condition = 1
AND somethingelse = 'value'
) > 0 THEN
-- run the query again to get the number of rows
(
SELECT count(*)
FROM sometable
WHERE condition = 1
AND somethingelse = 'value'
)
ELSE 0
END
SELECT 'Hello StackOverflow'
,'Thanks for reading this question'
,CASE
WHEN
(
SELECT count(*)
FROM sometable
WHERE condition = 1
AND somethingelse = 'value'
) AS subqry_count > 0 THEN
-- use the subqry_count, which fails... "Incorrect syntax near the keyword 'AS'"
subqry_count
ELSE 0
END

Just use the subquery as the source you are selecting from:
SELECT 'Hello StackOverflow'
,'Thanks for reading this question'
,CASE subqry_count.Cnt
WHEN 0 THEN 0
ELSE subqry_count.Cnt
END
FROM ( SELECT count(*) AS Cnt
FROM sometable
WHERE condition = 1
AND somethingelse = 'value'
) subqry_count
As an aside, if you are just going to return 0 if the output from COUNT is 0, then you don't even need to use a CASE statement.

Related

How to use a column value in one of the select statement in the join in postgresql

I'm updating sitename as below. But then I need to utilize the levelindex from a in another query which is getting joined with the first query.
update billofquantity_temp a
set sitename = b.boqitemname
from (
select a.* from
(
select levelindex,productno,boqitemid,boqitemname,fileid from billofquantity_temp
where productno ='' and levelindex !='' //first query
) a
join
(
select distinct substring(levelindex,1,length(a.levelindex) lblindex from billofquantity_temp
where boqitemid !='' and levelindex !=''
and length(levelindex) > 2
) b on a.levelindex=b.lblindex // second query
) b
where a.levelindex=b.levelindex;
I need to use the a.levelindex in second query to get the substrings of the it's length. But this throws error invalid reference to FROM-clause entry for table "a"
Is there any other way to use the column from query 1 in 2 while joining them?
Update:
Based on kims answer, I could get the selection done but there is error syntax error at c.a.levelindex. There error is thrown even with c.levelindex.
A slight modification to the query made no errors but the intened update doesn't happen. Instead only one particular values is updated. Below is the updated query to remove errors
update billofquantity_temp d
set sitename = c.boqitemname
from (
select * from (
select levelindex, boqitemname from billofquantity_temp
where productno = '' and levelindex != '' -- first query
) a
join (
select distinct levelindex lblindex from billofquantity_temp
where boqitemid != '' and levelindex != '' and length(levelindex) > 2 ) b
on a.levelindex = substring(b.lblindex, 1, length(a.levelindex)) -- second query
) c
where d.levelindex = c.lblindex;
Move the computation of lblindex outside the sub-select to the on clause:
update billofquantity_temp d
set sitename = c.boqitemname
from (
select *
from (
select levelindex, boqitemname
from billofquantity_temp
where productno = '' and levelindex != '' -- first query
) a
join (
select distinct levelindex
from billofquantity_temp
where boqitemid != '' and levelindex != '' and length(levelindex) > 2
) b
on a.levelindex = substring(b.levelindex, 1, length(a.levelindex)) -- second query
) c
where d.levelindex = c.a.levelindex
;
I've also used c and d to avoid confusion from using a and b twice, added a missing ), and removed unused fields from select.

DB2 SQL, cant define column as

I have some SQLthat is part of that is a section of a with statement
And I keep getting an error that "NEWID" is not valid in the context where it is used sqlstate 42703.
Update: The error has been comming from the group by clause using a having function I didnt put in the original code as I thought it wasnt the issue.So I updated the code to show the full version.
Does anyone know what the problem is with the statement?
HATSTABLE1 (HATId, NewID) as (
select HA.HATId as "ID",
round(
cast(
sum(
case when HA.ID = 4 or
HA.ID < 0
then 1 else 0 end
) AS FLOAT
) / count(*) * 100,
2
) AS NewID
from Hats T
join Heads HD on
T.ID=HD.HatID
group by T.ID
having NewID >1
try it
with tmp as (
select T.HATId as "ID",
sum(case when T.ID = 4 or HA.ID < 0 then 1 else 0 end) as sum1,
count(*) as nb
from Hats T
group by T.HATId
)
select HATId, round(cast(sum1 as decimal)/ nb * 100, 2) NewID
from tmp

SQL Select where exclusive Or /Case

I need a query based on an exclusive Or statement for this I try using the case but I won't get a result in case of Null...
...
and b.[U_Periode] = CASE
when (b.U_Periode= #period) then #period
when (b.U_Periode is NULL ) then null
end
...
The Case that won't be catched is... if B.U_Status is null and b.U_Periode is null.
If the var Periode match the Value and the U_Status = 0 or 1
the only way getting this working for me was this:
...
and
ISNULL( b.[U_Status],'0') = CASE
when (b.U_Status= '1') then '1'
when (isnull( b.U_Status,'0')= '0') then '0'
end
and
ISNULL (b.[U_Periode],'01.01.1901') = CASE
when (b.U_Periode= #period) then #period
when (ISNULL (b.U_Periode,'01.01.1901') = '01.01.1901' ) then '01.01.1901'
end
are there any other better solutions for this?
Best regards
Oliver
Okay... here is my Problem
Table1
InsID ContractID
1 1
2 1
Table2
ID insid Period Status Count
1 1 null null 100
2 1 30.09.2015 1 500
3 2 null null 100
4 2 30.09.2015 1 500
Case '31.08.2015'
in total Value should be 200
in case of '30.09.2015'
the Value should be 1.000
XOR /OR will do the same in this case.
Value case '31.08.2015' = 200
value Case ' 30.09.2015 = 2200
So this is somesing like a subquery
left join (
[dbo].[Table2]b
inner join [dbo].[Table 3]K on k.DocEntry = b.DocEntry and CAST( k.U_CSetID as int) >0
)
on b.[U_InsID] in(select... but here I should have an if statement...
If there are results matching the Date join this
If not than join the result NULL is matching to periode...
Okay.. here is the complete query
the Table2 with the Date of 31.08.2015 should have one Record that include
B_STATUS = Null and B.Preiode = null and there is no available record with the U_Periode '31.08.2015' and a Staus ...
with a date of 30.09.2015
there is a Record matching U_Period = '30.09.2015' in this case the Record with U_Period=null should not effect the result...
Declare #period as varchar(20)= '31-08-2015 00:00:00'
declare #Customer as Varchar(15)='12345'
declare #Contract as varchar(30) = '123'
declare #test as varchar(1) = null
select SUM(cast(K.U_Count as decimal))as counter, K.U_CounterTyp
from [dbo].[Table1] a
left join (
[dbo].[Table2]b
inner join [dbo].[Table 3]K on k.DocEntry = b.DocEntry and CAST( k.U_CSetID as int) >0
)
on b.[U_InsID]=a.[insID] and b.[U_ObjectType]in ('5','1') and
ISNULL( b.[U_Status],'0') = CASE
when (b.U_Status= '1') then '1'
when (isnull( b.U_Status,'0')= '0') then '0'
end
and
ISNULL (b.[U_Periode],'01.01.1901') = CASE
when (b.U_Periode= #period) then #period
when (ISNULL (b.U_Periode,'01.01.1901') = '01.01.1901' ) then '01.01.1901'
end
where a.[customer] =#Customer and a.[Status]='A' and a.[U_ContrCount]='1'
and a.[manufSN] in(
select c.[ManufSN] from [dbo].[Table4] c
inner join [dbo].[OCTR]d on d.[ContractID] = c.[ContractID]
where c.[ManufSN]=a.[manufSN]
and d.[CstmrCode] = a.[customer] and d.[ContractID]=#Contract
)
group by K.U_CounterTyp
you must use the "^" operand, this is XOR operand in TSQL
expression ^ expression
the expression must return or 0 or 1...
stupid example:
WHERE (name like "stackoverflow") ^ (age > 10)
font: https://msdn.microsoft.com/en-us/library/ms190277(v=sql.105).aspx
Update for your check
WHERE (CONVERT(VARCHAR(10), a.[U_Periode], 104) = '30.08.2015') != (a.U_Periode IS NULL)
Olay here is my funktion that chek either a Date Result is there or not.
The only thing is, that the performance is not the best if I run hundreths of sentences ... foreach record (up to app. 1000) I need to query each subtable... and there are many many records in...
Anyway this is the function
CREATE FUNCTION fn_GetInsCounters(#InsId as Varchar(30), #Date as datetime)
returns datetime
as
begin
declare #count as int = 0
declare #Retruns as Datetime
set #count =
(
select count( b.Docentry)
from [dbo].[Table2]b
where b.U_Insid =#InsID
and b.U_Status <> '2'
and b.[U_ObjectType]in ('5','1')
and b.U_Periode=#Date
)
if(#count>0)
begin
set #Retruns = #date
end
else
begin
set #Retruns = '01.01.1901'
end
return #Retruns
end
if anyone gets a better idea???
Best regards
Oliver

CTE with CASE statement

I'm trying a query like this;
WITH CTE AS
(
SELECT
ID, NAME, DEPT,
CASE WHEN Fixed = 1 THEN 'Yes' ELSE '' END,
CASE WHEN NotFixed = 1 THEN 'Yes' ELSE '' END,
)
When I try to execute this query, I'm getting error like
No Column was specified for column 4 of CTE
What's wrong with the query?
Read the error message: You forgot to give your calculated columns a name. This goes for both column 4 and column 5. So change your query to something like this:
WITH CTE AS
(
SELECT
ID, NAME, DEPT,
CASE WHEN Fixed = 1 THEN 'Yes' ELSE '' END AS [Expr1],
CASE WHEN NotFixed = 1 THEN 'Yes' ELSE '' END AS [Expr2],
. . .
)
Feel free to change [Expr1] and [Expr2] to something more meaningful...

unexplained error in sql execution

UPDATE amc_machine b
SET with_parts = a.with_parts,
amc_validity_upto = a.amc_validity_upto
FROM (SELECT CASE
WHEN count(*) > 0 THEN (SELECT DISTINCT ON (machine_id) with_parts, amc_validity_upto, machine_id
FROM amc_amcdetail
WHERE machine_id = 2 AND id != 1
ORDER BY machine_id, amc_validity_upto DESC)
WHEN count(*) = 0 THEN (SELECT FALSE AS with_parts, NULL AS amc_validity_upto, 2 AS machine_id)
END AS a
FROM (SELECT DISTINCT ON (machine_id) with_parts, amc_validity_upto, machine_id
FROM amc_amcdetail
WHERE machine_id = 2
ORDER BY machine_id, amc_validity_upto
) AS T) AS foo
WHERE a.machine_id = b.id
The error shown is
ERROR: subquery must return only one column
LINE 5: WHEN count(*) > 0 THEN (SELECT DISTINCT ON (machine_id) w...
Can anyone tell what seems to be the problem.
Basically the query is to update on table b with data from table a if exists, else update with null , false as the case is.
The query executes when standalone. I am using Postgres 9.3, but deployment will be on postgres9.1
The subquery returns 3 columns
SELECT DISTINCT ON (machine_id) with_parts, amc_validity_upto, machine_id
Make it return only one
SELECT DISTINCT ON (machine_id) with_parts