Case condition broken need assistance to fix - sql

New to SQL, so please accept my apologies. A query was created that when
If HBL_CLNT_CAT._HS_EB_CODE1 = 'BF' then value = TBM_BILLGRP._HS_EB_DET1
If HBL_CLNT_CAT._HS_EB_CODE2 = 'BF' then value = TBM_BILLGRP._HS_EB_DET2
However of the _HS_EB_DET# exceeds 100 characters add a '*'.
With assistance a query was developed, however it broken the condition rules in that the 'then statement/action would fail because it was greater number than the condition statement (select _hs_eb_code1 from hbl_cat where hs_eb_code = 'bf' that returns only 1 record).
select
case when len(format) > 100
then left(format, 100) + '*'
else format
end as format
from
( select
case when exists ( select _hs_eb_code1
from hbl_cat
where hs_eb_code = 'bf'
)
then tbm_bllgrp._hs_eb_det1
end
) as format
from tbm_bllgrp

Formatting the code would have helped you find the error. Try this:
select
case when len(format) > 100
then left(format, 100) + '*'
else format
end as format
from
( select
case when exists ( select _hs_eb_code1
from hbl_cat
where hs_eb_code = 'bf'
)
then tbm_bllgrp._hs_eb_det1
end as format
from tbm_bllgrp
) as tmp

The above query is broken in several places. A working statement could look like this:
SELECT CASE
WHEN len(x.myval) > 100 THEN
left(x.myval,100) + '*'
ELSE
x.myval
END AS format
FROM (
SELECT CASE
WHEN h.HS_EB_CODE1 = 'BF' THEN
t._HS_EB_DET1
WHEN h._HS_EB_CODE2 = 'BF' THEN
t._HS_EB_DET2
ELSE
'unknown option'
END AS myval
FROM HBL_CLNT_CAT AS h
JOIN TBM_BILLGRP AS t ON ??? -- how are the two tables connected?
WHERE ??? -- some condition or do you want all rows in the table?
) AS x
But you need to tell us first, how TBM_BILLGRP and HBL_CLNT_CAT can be joined, and how you select your rows.
BTW, upper case is pointless in SQL-Server. Identifiers are case-insensitive as long as they are not enclosed in double quotes " " or brackets [ ].

Related

How to check unique values in SQL

I have a table named Bank that contains a Bank_Values column. I need a calculated Bank_Value_Unique column to shows whether each Bank_Value exists somewhere else in the table (i.e. whether its count is greater than 1).
I prepared this query, but it does not work. Could anyone help me with this and/or modify this query?
SELECT
CASE
WHEN NULLIF(LTRIM(RTRIM(Bank_Value)), '') =
(SELECT Bank_Value
FROM [Bank]
GROUP BY Bank_Value
HAVING COUNT(*) = 1)
THEN '0' ELSE '1'
END AS Bank_Key_Unique
FROM [Bank]
A windowed count should work:
SELECT
*,
CASE
COUNT(*) OVER (PARTITION BY Bank_Value)
WHEN 1 THEN 1 ELSE 0
END AS Bank_Value_Unique
FROM
Bank
;
It works also, but I found solution also:
select CASE WHEN NULLIF(LTRIM(RTRIM(Bank_Value)),'') =
(select Bank_Value
from Bank
group by Bank_Value
having (count(distinct Bank_Value) > 2 )) THEN '1' ELSE '0' END AS
Bank_Value_Uniquness
from Bank
It was missing "distinct" in having part.

How to use an SQL Comparator in the base 'Case' selector in the 'When' logic without having to re-write conditions

I have an SQL query joined on multiple tables (all INNER JOINS).
The below is an example of the query I am trying to run (the ? is to illustrate the position in which I presume the answer to my question will be rectified).
Case
(
SELECT Count(ID)
FROM CPD_Candidates cpdCan
WHERE
cpdCan.CandidateID = can.CandidateID
AND
(
cpdCan.DateEnded >= GETDATE()
OR
coalesce(cpdCan.DateEnded, '') = N'1-Jan-1900'
)
AND
cpdCan.Deleted <> 1
)
When ? > 0 then 'Bigger' else 'Equal or Smaller' End
)
The idea with the above is that instead of the ? the actual value I want to compare against would be Count(ID), if it's greater than 0 I want it to SELECT 'Bigger', otherwise it should SELECT 'Equal or Smaller'. So a more-accurate depiction of what I wish to run would be the below.
Case
(
SELECT Count(ID)
FROM CPD_Candidates cpdCan
WHERE
cpdCan.CandidateID = can.CandidateID
AND
(
cpdCan.DateEnded >= GETDATE()
OR
coalesce(cpdCan.DateEnded, '') = N'1-Jan-1900'
)
AND
cpdCan.Deleted <> 1
)
When
Count(cpdCan.ID) > 0 then 'Bigger' else 'Equal or Smaller' End
)
Of course there is a syntax error above but I am enquiring as to whether it is possible to compare like in the above SQL query structure but replacing Count(cpdCan.ID) > 0 with some other means to achieve that value & logic?
If this is un-achievable in SQL Server 2016 what other means would be a better solution to this XY?
I think that you mean:
case when
(
SELECT Count(ID)
FROM CPD_Candidates cpdCan
WHERE
cpdCan.CandidateID = can.CandidateID
AND (cpdCan.DateEnded >= GETDATE() OR coalesce(cpdCan.DateEnded, '') = N'1-Jan-1900')
AND cpdCan.Deleted <> 1
) > 0
then 'Bigger'
else 'Equal or Smaller'
End

Case Expression on a created column using Microsoft SQL

Within a view I put put together a select statement within a case and delcared it as a column. The column name is 'IR2'
How can I case off of the column 'IR2'?
I end up getting an error which says 'Invalid Column Name 'IR2'.
What are my work around options?
case when r.ana = 'nh3' and r.serv='energy' and exists( select 1 from results x where x.no=r.no and x.ana='nh3' and x.sa='rejected' and x.serv <> 'energy')
then '*' else r.sa end as IR2,
CASE IR2 WHEN 'Released' then
''
ELSE
'*'
END AS IR
You can use a subquery or CTE. But another fun way in SQL Server is using outer apply:
select v.IR2,
(case IR2 when 'Released' then '' else '*' end) as ir
from . . . outer apply
(values (case when r.ana = 'nh3' and r.serv='energy' and
exists( select 1 from results x where x.no=r.no and x.ana='nh3' and x.sa='rejected' and x.serv <> 'energy')
then '*' else r.sa
end)
) v(IR2)
CTE would be the best choice. If you want to continue with current statement, you need to put a copy of the case statement in other case statement. Very messy code.
SELECT
case when r.ana = 'nh3' and r.serv='energy' and
exists( select 1 from results x where x.no=r.no and x.ana='nh3' and x.sa='rejected' and x.serv <> 'energy')
then '*' else r.sa end as IR2,
CASE
(case when r.ana = 'nh3' and r.serv='energy'
and exists( select 1 from results x where x.no=r.no and x.ana='nh3' and x.sa='rejected' and x.serv <> 'energy')
then '*' else r.sa end)
WHEN 'Released' then
''
ELSE
'*'
END AS IR

Check and Change for empty or null value of column in SQL?

How can I change column text Not Exists when it is empty or null ?
My query :
Select TOP 1 ISNULL(NULLIF(DR.Name,''),'Not Exists') as Name,
DR.Name as Name ,Coalesce(NullIf(rtrim(DR.Name),''),'Not Exist') as Name,
Name = case when DR.Name is null then 'Not Exists'
when DR.Name='' then 'Not Exists' else DR.Name end
from Transfer TR
join Driver DR on DR.OID=TR.DriverID
WHERE TR.TruckID=51 AND TR.Statues<>7 and TR.DateScheduled<GETDATE()
AND TR.DateScheduled>=DATEADD(DAY,-7,GETDATE()) ORDER BY TR.OID DESC
Result :
If you just need a single column, then you can use a sub-select, this way when no rows are returned by the query you will still get not exists:
SELECT Name = ISNULL(( SELECT TOP 1 NULLIF(DR.Name,'')
FROM Transfer AS TR
INNER JOIN Driver AS DR
ON DR.OID = TR.DriverID
WHERE TR.TruckID = 51
AND TR.Statues <> 7
AND TR.DateScheduled < GETDATE()
AND TR.DateScheduled >= DATEADD(DAY, -7, GETDATE())
ORDER BY TR.OID DESC), 'Not Exists');
If you need multiple columns then you could union your Not Exists record to the bottom of the query, place all this inside a subquery then select the top 1 again, ensuring that your actual value takes precedence (by adding the column SortOrder):
SELECT TOP 1 Name, SomeOtherColumn
FROM ( SELECT TOP 1
Name = NULLIF(DR.Name,''),
SomeOtherColumn,
SortOrder = 0
FROM Transfer AS TR
INNER JOIN Driver AS DR
ON DR.OID = TR.DriverID
WHERE TR.TruckID = 51
AND TR.Statues <> 7
AND TR.DateScheduled < GETDATE()
AND TR.DateScheduled >= DATEADD(DAY, -7, GETDATE())
ORDER BY TR.OID DESC
UNION ALL
SELECT 'Not Exists', NULL, 1
) AS t
ORDER BY SortOrder;
I'm not entirely sure I understand your question, but if you are trying to catch nulls and empty strings "in one go", try this:
select TOP 1
case when length(trim(coalesce(DR.Name, ''))) = 0 then
'Not Exists'
else
DR.Name
as Name
....
The coalesce catches the NULLs and sets a replacement value. The trim gets rid of any padding and the length checks if what is left is an empty string --> so this covers nulls, padded- and non-padded trivial strings.
Assuming the value has regular spaces, the following would keep your approach:
Select TOP 1 ISNULL(NULLIF(ltrim(rtrim((DR.Name))), ''), 'Not Exists') as Name,
I would probably go with the more explicit:
select top 1 (case when ltrim(rtrim((DR.Name)) = '' or DR.Name is null then 'Not Exists'
else DR.Name end) as Name
Unless you also wanted the spaces removed from Name in the output.
If you have other characters, then you can use ASCII() to find them. Something like:
select ASCII(LEFT(DR.Name, 1))
. . .
where LEFT(DR.Name, 1) NOT LIKE '[a-zA-Z0-9 ]' -- you can expand this list of allowed characters
It seems to me you are not actually looking for a way to replace an empty string with 'Not Exists', but an empty result set.
In other words: It looks like you are looking for a way to show 'Not Exists' in case your query returns no rows. If it is this what you are looking for, then first "add" a 'Not Exists' record to your result set and then show the best row, i.e. the desired row in case such a row exists, else your 'Not Exists' row.
select top 1 name
from
(
select name, tr.oid
from transfer tr
join driver dr on dr.oid=tr.driverid
where tr.truckid=51 and tr.statues<>7 and tr.datescheduled<getdate()
and tr.datescheduled>=dateadd(day,-7,getdate())
union all
select 'Not Exists', -1
)
order by oid desc;
I chose -1 for the dummy OID. It must be a value smaller than any real OID. So if you have negative values, make that value even smaller.

Select Case query not working

New to SQL and in the process of developing query, with the to replicate part of an ETL process.
A billing code1 = bf, is then set to debt code 1. If billing field (debt code) exceeds 100 characters then add '*' as prefix.
However query will fall down because billing code1 = bf returns a single resultset to a debt code1 that returns large resultset.
select
case when len(format) > 100 then left(format, 100) + '*'
else format end as format
from (select case when exists (select _hs_eb_code1 from hbl_cat where hs_eb_code = 'bf)
then tbm_bllgrp._hs_eb_det1 end) as format
from tbm_bllgrp
Ideas welcomed.
select
case when len(format) > 100 then left(format, 100) + '*'
else format end as format
from tbm_bllgrp b
inner join hbl_cat hc on hc._hs_eb_code1 = b._hs_eb_det1
This is just a guess since I don't have your exactl schema and expected output, but I hope this gives you some ideas