Case expression with subquery error: coud not be bound - sql

I'm trying to use a Case Expression when a I have a subquery, and SQL keeps me returning
The multi-part identifier "local1.DescricaoLotacao" could not be
bound.
CASE WHEN (SELECT local1.[DescricaoLotacao] FROM sgp.dbo.[LOTACAO] AS [local1]
WHERE local1.IdLotacao = (SELECT TOP 1 [uai].[IdLotacao] FROM sgp.dbo.[UnidadeAdministrativaInterna] AS [uai]
WHERE uai.[CodigoPessoal] = p.[CodigoPessoal] AND uai.[DataFinal] IS NULL ORDER BY [uai].[DataInicial] DESC)
) IS NOT NULL
THEN local1.[DescricaoLotacao]
ELSE ''
END,
I know it's why my local.descricaoLotacao is out of my parentheses. But I don't know how to fix it. I thing there is another way to do this kind of select.

If you are sure that the query will return only 1 row then instead of CASE use COALESCE():
COALESCE(
(
SELECT local1.[DescricaoLotacao] FROM sgp.dbo.[LOTACAO] AS [local1]
WHERE local1.IdLotacao = (
SELECT TOP 1 [uai].[IdLotacao]
FROM sgp.dbo.[UnidadeAdministrativaInterna] AS [uai]
WHERE uai.[CodigoPessoal] = p.[CodigoPessoal] AND uai.[DataFinal] IS NULL
ORDER BY [uai].[DataInicial] DESC
),
''
)

I suggest using EXISTS
This is assuming the local1.[DescricaoLotacao] portion exists outside of the CASE WHEN section.
CASE WHEN EXISTS (SELECT local1.[DescricaoLotacao] FROM sgp.dbo.[LOTACAO] AS [local1]
WHERE local1.IdLotacao = (SELECT TOP 1 [uai].[IdLotacao] FROM sgp.dbo.[UnidadeAdministrativaInterna] AS [uai]
WHERE uai.[CodigoPessoal] = p.[CodigoPessoal] AND uai.[DataFinal] IS NULL ORDER BY [uai].[DataInicial] DESC)
)
THEN local1.[DescricaoLotacao]
ELSE ''
END

Related

Use rownum to always get non null value

select case when (CUST.ADDRESS_TYPE='OFFICE') then
(Select MOBILE
FROM cust_table CUST
where CID = Deal.CID
and ADDRESS_TYPE = 'CURRES'
and rownum = 1)
else
CUST.MOBILE
end as MOBILE
FROM cust_table CUST
RIGHT OUTER JOIN (SELECT CID CID
, WNAME
, APPLICANT_TYPE
FROM deal_table ) DEAL
ON DEAL.CID = CUST.CID
AND APPLICANT_TYPE = 'P'
and mailing_add = 'true'
WHERE WNAME='22135'
and rownum = 1
#MOBILE#
NULL
647432923
OR
#MOBILE#
74238423
NULL
This query returns a column named 'MOBILE ' with two rows, one of the entries being always null when I dont use rownum = 1 at the end, but if I put rownum = 1 towards the end then in some cases it returns null value and in some cases non null value. How can I use rownum so that the query always returns non null value.
Do not use rownum for this. rownum will give you the number of the row after your query has been run. Use a properly defined ORDER BY clause to get your NULLS at the end and only fetch first row.
<your query>
WHERE wname='22135'
ORDER BY mobile NULLS LAST
FETCH FIRST 1 ROWS ONLY

CASE or IF statement in WHERE clause

How can I use CASE statement or IF statement in WHERE clause ?
I am trying to apply a check on the basis of COUNT
SELECT * FROM sometable
WHERE CASE WHEN (SELECT COUNT(*) FROM sometable s WHERE SP = 2 AND sometable.id = s.id) > 2 THEN sometable.SP IS NOT NULL END
So basically if the count of rows is more than 1 it should apply IS NOT NULL condition else it should not.
Your logic suggests something like:
SELECT s.*
FROM (SELECT s.*,
SUM(CASE WHEN sp = 2 THEN 1 ELSE 0 END) OVER (PARTITION BY id) as cnt_2
FROM sometable s
) s
WHERE cnt_2 <= 2 OR s.sp is not null;
That seems equivalent. The logic doesn't seem particularly useful though.

How to use case statement inside where clause of sql 2000

I have a query that contains a WHERE clause with a CASE statement in it (See code below), somehow it doesn't seem to work.
select * FROM
details
where orgcode in
(case when orgtype='P' then
(SELECT distinct [PCode]
FROM [GPOS_Extract].[dbo].[GP8288List])
else
0 end )
How about
select * FROM details
where (orgtype <> 'P' AND orgcode = 0)
or orgcode in
(
SELECT distinct [PCode]
FROM [GPOS_Extract].[dbo].[GP8288List]
)
Or try this:
SELECT * FROM details
WHERE details.orgcode IN
( SELECT DISTINCT
(CASE WHEN details.orgtype='P'
THEN [GPOS_Extract].[dbo].[GP8288List].PCode
ELSE 0 END)
FROM [GPOS_Extract].[dbo].[GP8288List] )
I think the following is the logic that is equivalent to your attempt:
select *
FROM details
where (orgtype = 'P' and
orgcode in (SELECT distinct [PCode]
FROM [GPOS_Extract].[dbo].[GP8288List]
)
) or
((orgtype <> 'P' or orgtype is NULL) and orgcode = 0);
what about this,
select a.*,case when orgtype='P' then PCode else '0' end FROM
details a
left join [GPOS_Extract].[dbo].[GP8288List] b on a.orgcode=b.PCode
case returns a single value. You are trying to use it as though it returns a result set. What you want is:
select * FROM details d
where (orgtype = 'p'
And exists (Select *
From GPOS_Extract.dbo.GP8288List
Where PCode = d.orgcode))
or (orgtype <> 'p' And orgcode= 0)

Null value in order by clause

I have a weird scenario, in which I need to keep all the rows at top in which X column has NULL value else sort by Y column. Can you help me in writing query.
ORDER BY CASE WHEN X IS NULL THEN 0 ELSE 1 END, Y
You can use a CASE statement in ORDER BY:
ORDER BY
CASE WHEN X IS NULL THEN 0 ELSE 1 END ASC, Y
Here you go, this will work with any sql platform -- for a specific platform there might be a better way to do it.
SELECT * FROM
(
SELECT 1 AS orderC, *
FROM tableName
WHERE Xcolumn is null
UNION ALL
SELECT 2 AS orderC, *
FROM tableName
WHERE Xcolumn is not null
)
ORDER BY orderC ASC, columnY
Note, if you don't want orderC to be in the output, just specify all the other columns in the outer select.
Sharing what I learned before using:
ORDER BY FIELD(Xcolumn, NULL) DESC, Ycolumn DESC
SELECT * FROM TABLENAME ORDER BY X ,Y
You can use query like below:
SELECT * FROM Emp WHERE empId= 6 AND DELETED = 0
ORDER BY CASE WHEN DOB IS NULL THEN 0 ELSE 1 END
, CREATETIMESTAMP.
for more details you can see here

CASE statement with IN in WHERE clause

I'm trying to create the following WHERE clause:
AND CASE #SomePRarmeter
WHEN 'this' THEN
user_id IN (SELECT * FROM dbo.func_Id1(#User))
WHEN 'that' THEN
user_id IN (SELECT user_id from dbo.func_Ids2(#OrgsForReporter)
END
But I'm getting an error: Incorrect syntax near the keyword 'IN' (in the first condition) , although separately both of those conditions work. What would be the correct way to make such a statement work?
Thanks!
Try
AND (
(#SomePRarmeter = 'this' AND user_id IN (SELECT * FROM dbo.func_Id1(#User)))
OR
(#SomePRarmeter = 'that' AND user_id IN user_id IN (SELECT user_id from dbo.func_Ids2(#OrgsForReporter)))
)
You are doing select * in a subquery. You need to return only one column:
(SELECT * FROM dbo.func_Id1(#User))
to this:
(SELECT YOUR_USER_ID_COLUMN FROM dbo.func_Id1(#User))
A case statement must result in a value, not an expression. So this won't work:
select case when 1=1 then 1 in (1,2,3) end
But this will work;
select case when 1=1 then 1 end
The value can be the result of a subquery. So one solution would be to rewrite the where clause like:
CASE #SomePRarmeter
WHEN 'this' THEN
(SELECT count() FROM dbo.func_Id1(#User) f where f.user_id = t.user_id))
WHEN 'that' THEN
(SELECT count() from dbo.func_Ids2(#OrgsForReporter) f where f.user_id = t.user_id))
END > 1
Now it returns the number of matching rows. You can then filter with case ... end > 1.
I'd break this out:
IF 'this'
SELECT
...
WHERE user_id IN (SELECT * FROM dbo.func_Id1(#User))
ELSE IF 'that'
SELECT
...
WHERE user_id IN (SELECT user_id from dbo.func_Ids2(#OrgsForReporter))
CASE ... END returns an expression, not a piece of literal SQL code. Rather than:
AND CASE foo WHEN bar THEN bla=ble END -- Wrong
... you have to use this:
AND bla = CASE foo WHEN bar THEN ble END -- Right
In your case, you can do something on this line:
-- Untested
AND (
(#SomePRarmeter='this' AND user_id IN (SELECT * FROM dbo.func_Id1(#User)))
OR (#SomePRarmeter='that' AND user_id IN (SELECT user_id from bo.func_Ids2(#OrgsForReporter))
)