Select Records from First OR occurence within a multiple AND/OR T-SQL statement within a function - sql

I have the following SQL (example):
SET #Return_Value = = (SELECT Top 1
(CASE WHEN .... THEN ColumValue1 ELSE ColumValue2 END)
FROM TableA WHERE (Lots of AND Statements)
AND
(
(bla1)
OR
(bla2)
OR
(bla3)
)
The bla1, etc are logic to retrieve colum values from TableA. How can I return the values from bla1 if they were found without executing bla2 or bla3 because those might overwrite what I'm looking for? In other words I only want to execute OR statements if the previous one didn't find data, all this within a function.

You can use a case expression as :
SET #Return_Value = (SELECT Top 1
(CASE WHEN .... THEN ColumValue1 ELSE ColumValue2 END)
FROM TableA WHERE (Lots of AND Statements)
AND
( 1 = case when condition1 then 1
case when condition2 then 1
case when condition3 then 1
end
);

you can use order by, like
select Top 1
CASE WHEN .... THEN ColumValue1 ELSE ColumValue2 END
FROM TableA
WHERE
(Lots of AND Statements) AND
(
(bla1) OR
(bla2) OR
(bla3)
)
order by
case
when (bla1) then 1
when (bla2) then 2
when (bla3) then 3
else 999
end
Or you can try to simplify it (but you have to check performance):
select Top 1
CASE WHEN .... THEN ColumValue1 ELSE ColumValue2 END
FROM TableA
outer apply (
select
case
when (bla1) then 1
when (bla2) then 2
when (bla3) then 3
end as T
) as C
WHERE
(Lots of AND Statements) and
C.T is not null
order by C.T
or, for example, you can use union, something like this:
with cte as (
select Top 1
CASE WHEN .... THEN ColumValue1 ELSE ColumValue2 END as data
FROM TableA
WHERE
(Lots of AND Statements)
), cte2 as (
select top 1 data, 1 as c from cte where (bla1)
union all
select top 1 data, 2 as c from cte where (bla2)
union all
select top 1 data, 3 as c from cte where (bla3)
)
select top 1 data
from cte2
order by c

Related

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.

Get single row depending of conditional

I have a simple select query with some joins like:
SELECT
[c].[column1]
, [c].[column2]
FROM [Customer] AS [c]
INNER JOIN ...
So I do a left join with my principal table as:
LEFT JOIN [Communication] AS [com] ON [c].[CustomerGuid] = [com].[ComGuid]
this relatioship its 1 to *, one customer can have multiple communications
So in my select I want to get value 1 or 2 depending of condition:
Condition:
if ComTypeKey (from communication) table have a row with value 3 and have another row with vale 4 return 1 then 0
So I try something like:
SELECT
[c].[column1]
, [c].[column2]
, IIF([com].[ComTypeKey] = 3 AND [com].[ComTypeKey] = 4,1,0)
FROM [Customer] AS [c]
INNER JOIN ...
LEFT JOIN [Communication] AS [com] ON [c].[CustomerGuid] = [com].[ComGuid]
But it throws me two rows, beacause there are 2 rows on communication. My desire value is to get only one row with value 1 if my condition is true
If you have multiple rows you need GROUP BY, then count the relevant keys and subtract 1 to get (1, 0)
SELECT
[c].[column1]
, [c].[column2]
, COUNT(CASE WHEN [ComTypeKey] IN (3,4) THEN 1 END) - 1 as FLAG_CONDITION
FROM [Customer] AS [c]
INNER JOIN ...
LEFT JOIN [Communication] AS [com]
ON [c].[CustomerGuid] = [com].[ComGuid]
GROUP BY
[c].[column1]
, [c].[column2]
I'm not really sure I understand.
This will literally find if both values 3 and 4 exist for that CustomerGuid, and only select one of them in that case - not filtering out any record otherwise.
If this is not what you want, providing sample data with the expected result would remove the ambiguity.
SELECT Field1,
Field2,
...
FieldN
FROM (SELECT TMP.*,
CASE WHEN hasBothValues = 1 THEN
ROW_NUMBER() OVER ( PARTITION BY CustomerGuid ORDER BY 1 )
ELSE 1
END AS iterim_rn
FROM (SELECT TD.*,
MAX(CASE WHEN Value1 = '3' THEN 1 ELSE 0 END) OVER
( PARTITION BY CustomerGuid ) *
MAX(CASE WHEN Value1 = '4' THEN 1 ELSE 0 END) OVER
( PARTITION BY CustomerGuid ) AS hasBothValues
FROM TEST_DATA TD
) TMP
) TMP2
WHERE interim_rn = 1

sql select statement select sum where

I have two temp tables (below), the first marks one of five conditions. The second pulls from that table and does a sum and a count based on the condition. How could I get the second table to work with this, or a similar format?
select ID
,sum_value
,condition_field
,'condition_1' = case when condition_type in (1,2) then 1 else 0 end
,'condition_2' = case when condition_type in (3,4) then 1 else 0 end
--etc...
into #temp
from my_table
select ID
,sum_value
,'1_amt' = SUM(sum_value) from #temp where condition_1 = 1
,'1_cnt' = COUNT(ID) from #temp where condition_1 = 1
,'2_amt' = SUM(sum_value) from #temp where condition_2 = 1
,'2_cnt' = COUNT(ID) form #temp where condition_2 = 2
from #temp
You want something more like this:
SUM(CASE WHEN condition_1=1 THEN sum_value ELSE 0 END) AS 1_amt

T-Sql: turn multiple rows into one row

How does one turn these multiple rows into one row? N and Y are bool values.
Id IsPnt IsPms, IsPdt
1 N Y N
1 N Y N
1 Y N N
into this
Id IsPnt IsPms, IsPdt
1 Y Y N
Edit:
The query that produces the resultset looks like this
select b.id,
CASE mpft.PlanIndCd WHEN 'PBMN' THEN 1 ELSE 0 END AS IsPnt,
CASE mpft.PlanIndCd WHEN 'PBMT' THEN 1 ELSE 0 END AS IsPbt,
CASE mpft.PlanIndCd WHEN 'PBMS' THEN 1 ELSE 0 END AS IsPms
from vw_D_SomveViewName pb
-- bunch of joins
where mpft.PlanIndCd in ('HANR', 'PBMN','PBMT','PBMS','HAWR')
You can simply use MAX() on this if the values are really Y and N only.
SELECT ID, MAX(IsPnt) IsPnt, MAX(IsPms) IsPms, MAX(IsPdt) IsPdt
FROM tableName
GROUP BY ID
UPDATE 1
SELECT b.id,
MAX(CASE mpft.PlanIndCd WHEN 'PBMN' THEN 1 ELSE 0 END) AS IsPnt,
MAX(CASE mpft.PlanIndCd WHEN 'PBMT' THEN 1 ELSE 0 END) AS IsPbt,
MAX(CASE mpft.PlanIndCd WHEN 'PBMS' THEN 1 ELSE 0 END) AS IsPms
FROM vw_D_SomveViewName pb
-- bunch of joins
WHERE mpft.PlanIndCd in ('HANR', 'PBMN','PBMT','PBMS','HAWR')
GROUP BY b.ID
Will this work?
select
id,
max(IsPnt),
max(IsPms),
max(IsPdt)
from
table
GROUP BY
id
After the edit of your question, you can simply use the PIVOT table operator directly instead of using the MAX expression, something like:
SELECT
Id,
PBMN AS IsPnt,
PBMT AS IsPbt,
PBMS AS IsPms
FROM
(
SELECT
id,
mpft.PlanIndCd,
ROW_NUMBER() OVER(PARTITION BY id
ORDER BY ( SELECT 1)) AS RN
from vw_D_SomveViewName pb
-- bunch of joins
where mpft.PlanIndCd in ('HANR', 'PBMN','PBMT','PBMS','HAWR')
) AS t
PIVOt
(
MAX(RN)
FOR PlanIndCd IN ([PBMN], [PBMT], [PBMS])
) AS p;
You can see it in action in the following demo example:
Demo on SQL Fiddle
select Id, MAX(IPnt), MAX(IsPms), MAX(IsPdt)
from table etc

Get the distinct count of values from a table with multiple where clauses

My table structure is this
id last_mod_dt nr is_u is_rog is_ror is_unv
1 x uuid1 1 1 1 0
2 y uuid1 1 0 1 1
3 z uuid2 1 1 1 1
I want the count of rows with:
is_ror=1 or is_rog =1
is_u=1
is_unv=1
All in a single query. Is it possible?
The problem I am facing is that there can be same values for nr as is the case in the table above.
Case statments provide mondo flexibility...
SELECT
sum(case
when is_ror = 1 or is_rog = 1 then 1
else 0
end) FirstCount
,sum(case
when is_u = 1 then 1
else 0
end) SecondCount
,sum(case
when is_unv = 1 then 1
else 0
end) ThirdCount
from MyTable
you can use union to get multiple results e.g.
select count(*) from table with is_ror=1 or is_rog =1
union
select count(*) from table with is_u=1
union
select count(*) from table with is_unv=1
Then the result set will contain three rows each with one of the counts.
Sounds pretty simple if "all in a single query" does not disqualify subselects;
SELECT
(SELECT COUNT(DISTINCT nr) FROM table1 WHERE is_ror=1 OR is_rog=1) cnt_ror_reg,
(SELECT COUNT(DISTINCT nr) FROM table1 WHERE is_u=1) cnt_u,
(SELECT COUNT(DISTINCT nr) FROM table1 WHERE is_unv=1) cnt_unv;
how about something like
SELECT
SUM(IF(is_u > 0 AND is_rog > 0, 1, 0)) AS count_something,
...
from table
group by nr
I think it will do the trick
I am of course not sure what you want exactly, but I believe you can use the logic to produce your desired result.