IF Else string check condition in sql server - sql

I have a records like below :
Name Count
123456M2.txt NULL
123456M2.txt 15
123456M.txt NULL
First record shoud show me NULL, as there is a number after "M" letter in name and Count < 0
Second record shoud show me 1, and there is a number after "M" letter in name and Count > 0
Third record should show me "some number from another field" as, there is no number after "M" letter in name.
Can you guide me on how to write this query.
I am able to do CASE - WHEN query, but not able to proceed with IF ELSE condition of letter check
CASE
WHEN CHARINDEX('M', [FILE_NAME]) > 0 THEN 'COUNT'

You need to use multiple conditions for each WHEN in the CASE:
(psuedocode)
WHEN {Name contains 'M'} AND {character after 'M' is a number} AND {Count is NULL or < 0} THEN NULL
WHEN {Name contains 'M'} AND {character after 'M' is a number} AND {Count is NULL or < 0} THEN 1
etc...
there is no need to try to add IF..ELSE logic anywhere in your query.

I would phrase this as:
select . . .,
(case when name like '%M[0-9]%' and count > 0 then 1
when name like '%M[0-9]%' then 0
else "some number from another field"
end)
A case expression evaluates the conditions in order, stopping at the first one that evaluates to "true".
Your description is a bit unclear, because NULL is not < 0.

Try the following
DECLARE #TBL TABLE (Name VARCHAR(25), [Count] INT);
INSERT INTO #TBL VALUES
('123456M2.txt', NULL),
('123456M2.txt', 15),
('123456M.txt', NULL);
SELECT *,
CASE WHEN Name LIKE '%M[0-9]%' AND ([Count] IS NULL OR [Count] < 0) THEN --Check for NULL too cause NULL is not < 0
NULL
WHEN Name LIKE '%M[0-9]%' AND [Count] > 0 THEN
1
WHEN Name LIKE '%M.%' THEN
555 --Other value from other column
END AS Results
FROM #TBL;
Results:
+--------------+-------+---------+
| Name | Count | Results |
+--------------+-------+---------+
| 123456M2.txt | | |
| 123456M2.txt | 15 | 1 |
| 123456M.txt | | 555 |
+--------------+-------+---------+

Related

Unpivot multiple columns showing incorrect results

My initial query and result looks like below
SELECT * FROM (
SELECT S.CURRENCYCD , S.COMBINEDTXNAMOUNT
, S.INTERCHANGEAMOUNT
, S.OTHERCHARGEAMOUNT
,S.APPLIEDCHARGES
FROM
(SELECT X.CURRENCYCD,
CASE WHEN X.CombinedTxnAmount IS NULL THEN 0 ELSE X.CombinedTxnAmount END AS CombinedTxnAmount,
CASE WHEN X.InterchangeAmount IS NULL THEN 0 ELSE X.InterchangeAmount END AS InterchangeAmount,
CASE WHEN X.OtherChargeAmount IS NULL THEN 0 ELSE X.OtherChargeAmount END AS OtherChargeAmount,
CASE WHEN X.MinimumBillAdjustmentAmount IS NULL THEN 0 ELSE X.MinimumBillAdjustmentAmount END +
CASE WHEN X.AppliedChargeAmount IS NULL THEN 0 ELSE X.AppliedChargeAmount END AS APPLIEDCHARGES FROM
XMLTABLE (XMLNAMESPACES('http://www.eds.com/AgileCard/xsd/ACFMerchantStatement/2013/05' AS "acf",'http://www.eds.com/AgileCard/xsd/ACFMerchant/2012/03' as "acfMerchant")
,'/acf:Statement/acf:ChargeSummaryTotals/acf:ChargeSummaryTotalDetail' passing xmltype ('Myxml')
COLUMNS CURRENCYCD VARCHAR(4) PATH 'acfMerchant:CurrencyCd',
CombinedTxnAmount NUMBER PATH 'acf:CombinedTxnAmount',
InterchangeAmount NUMBER PATH 'acf:InterchangeAmount',
OtherChargeAmount NUMBER PATH 'acf:OtherChargeAmount',
MinimumBillAdjustmentAmount NUMBER PATH 'acf:MinimumBillAdjustmentAmount',
AppliedChargeAmount NUMBER PATH 'acf:AppliedChargeAmount'
)X ) S
The result is:
currencyCD | combinedTxnAmount | InterchangeAmount| OtherChangeAmount|AppliedCharges
GBP | 126.5 | 97.02 | 252.92 | 476.44
I am trying to unpivot this query result but for some reason I am not getting the expected result. Below is my unpivot query.
SELECT * FROM (
SELECT S.CURRENCYCD , S.COMBINEDTXNAMOUNT
, S.INTERCHANGEAMOUNT
, S.OTHERCHARGEAMOUNT
,S.APPLIEDCHARGES
FROM
(SELECT X.CURRENCYCD,
CASE WHEN X.CombinedTxnAmount IS NULL THEN 0 ELSE X.CombinedTxnAmount END AS CombinedTxnAmount,
CASE WHEN X.InterchangeAmount IS NULL THEN 0 ELSE X.InterchangeAmount END AS InterchangeAmount,
CASE WHEN X.OtherChargeAmount IS NULL THEN 0 ELSE X.OtherChargeAmount END AS OtherChargeAmount,
CASE WHEN X.MinimumBillAdjustmentAmount IS NULL THEN 0 ELSE X.MinimumBillAdjustmentAmount END +
CASE WHEN X.AppliedChargeAmount IS NULL THEN 0 ELSE X.AppliedChargeAmount END AS APPLIEDCHARGES FROM
XMLTABLE (XMLNAMESPACES('http://www.eds.com/AgileCard/xsd/ACFMerchantStatement/2013/05' AS "acf",'http://www.eds.com/AgileCard/xsd/ACFMerchant/2012/03' as "acfMerchant")
,'/acf:Statement/acf:ChargeSummaryTotals/acf:ChargeSummaryTotalDetail' passing xmltype ('myxml')
COLUMNS CURRENCYCD VARCHAR(4) PATH 'acfMerchant:CurrencyCd',
CombinedTxnAmount NUMBER PATH 'acf:CombinedTxnAmount',
InterchangeAmount NUMBER PATH 'acf:InterchangeAmount',
OtherChargeAmount NUMBER PATH 'acf:OtherChargeAmount',
MinimumBillAdjustmentAmount NUMBER PATH 'acf:MinimumBillAdjustmentAmount',
AppliedChargeAmount NUMBER PATH 'acf:AppliedChargeAmount'
)X ) S) UNPIVOT ((AMT) FOR TASK IN ((COMBINEDTXNAMOUNT) AS 'Combined Transaction Charge',
(INTERCHANGEAMOUNT) as 'Interchange'
,(OTHERCHARGEAMOUNT) as 'Other Charges'
,(APPLIEDCHARGES) as 'Charges Applied To Account'
))
Below is what this query returns:
currencycd | Task | AMT
GBP | Combined Transaction Charge | 126.5
GBP | Interchange | 0
GBP | Other Charges | 0
GBP | Charges Applied To Account | 0
Only the first unpivot value displays the amount correctly. Remaining values are displayed as zero.
Can someone point me what is going wrong with this query.

Impala SQL, return value if a string exists within a subset of values

I have a table where the id field (not a primary key) contains either 1 or null. Over the past several years, any given part could have been entered multiple times with one, or both of these possible options.
I'm trying to write a statement that will return some value if there is ever a 1 associated with the select statement. There are lots of semi-duplicate rows, some with 1 and some with null, but if there is ever a 1, I want to return true, and if there are only null values, I want to return false. I'm not sure how to code this though.
If this is my SELECT part,id from table where part = "ABC1234" statement
part id
ABC1234 1
ABC1234 null
ABC1234 null
ABC1234 null
ABC1234 1
I want to write a statement that returns true, because 1 exists in at least one of these rows.
The closest I've come to this is by using a CASE statement, but I'm not quite there yet:
SELECT
a1.part part,
CASE WHEN a2.id is not null
THEN
'true'
ELSE
'false'
END AS id
from table.parts a1, table.ids a2 where a1.part = "ABC1234" and a1.key = a2.key;
I also tried the following case:
CASE WHEN exists
(SELECT id from table.ids where id = 1)
THEN
but I got the error subqueries are not supported in the select list
For the above SELECT statement, how do I return 1 single line that reads:
part id
ABC1234 true
You can use conditional aggregation to check if a part has atleast one row with id=1.
SELECT part,'True' id
from parts
group by part
having count(case when id = 1 then 1 end) >= 1
To return false when the id's are all nulls use
select part, case when id_true>=1 then 'True'
when id_false>=1 and id_true=0 then 'False' end id
from (
SELECT part,
count(case when id = 1 then 1 end) id_true,
count(case when id is null then 1 end) id_false,
from parts
group by part) t

Can I issue a 'select exists' that checks for ALL specified fields?

Say that I have a database:
TITLE | RUNTIME | EPISODES
-------------------------------------------
The X-Files 42 202
Fringe NULL 100
Seinfeld 21 NULL
I want to issue a statement like SELECT EXISTS(SELECT title,runtime,episodes FROM shows); that will return 1 if all three of those fields are present (as for The X-Files) but 0 if any of them are empty/null (as with Fringe and Seinfeld).
Is this possible using SQL alone?
I would suggest just doing:
select t.*,
(case when title is not null and runtime is not null and episodes is not null
then 1 else 0 end) as HasAllThree
from table t;
The EXISTS function checks if rows exist, not columns. You can add a WHERE clause to meet your business objectives with the EXISTS and a CASE.
SELECT
CASE WHEN EXISTS(
SELECT * FROM shows
WHERE title IS NOT NULL
AND runtime IS NOT NULL
AND episodes IS NOT NULL
) THEN 1 ELSE 0 END

Show 2 count in 1 result

I need to display a single result so that I can extract it.
This is my table named 'TRY'
id | type |
01 | A |
01 | D |
01 | A |
My query is like this:
select
lpad(id,2,'0')||
lpad(count(case when type = 'A' then 1 end),3,'0')||
lpad(count(case when type = 'D' then 1 end),3,'0')||
lpad(count(case when type in ('A','D') then 1 end),3,'0') then 1 end)
as results
from
TRY
group by
id
,type
I want the result to show like this 01002001003 but instead I got 2 result which are like this
01002000002 and 01000001001. I just want to combine the count result as one.
I think that the main thing that you need to consider is how the GROUP BY clause actually works, as you have actually grouped by id and type meaning that you'll never have a positive count for type A and type D on the same row as they are not grouped together.
In your example I have noticed the following and worked to these parameters:
You want to GROUP BY id (not GROUP BY id, type)
Your returned result is a concatenated string which consists of
the id (padded to 2 characters)
the number of Type A's (padded to 3 characters)
the number of type D (padded to 3 characters)
the total number of A's and D's combined. (padded to 3 characters)
You actually also want to be using the SUM function instead of COUNT so something along the lines of the following should work:
Oracle/PLSQL
SELECT
LPAD(id,2,'0')
|| LPAD(SUM(CASE WHEN type = 'A' THEN 1 ELSE 0 END),3,'0')
|| LPAD(SUM(CASE WHEN type = 'A' THEN 1 ELSE 0 END),3,'0')
|| LPAD(SUM(CASE WHEN type = 'A' OR type = 'D' THEN 1 ELSE 0 END),3,'0')
AS results
FROM
TRY
GROUP BY
id
On the unlikely off-chance you're actually using SQL Server or another Database engine the LPAD function will not actually work so using something along the lines of the following may work instead. (Also added in case some non ORACLE users have a similar quandary and it's what I used to resolve your issue)
SELECT
[results] =
RIGHT('00' + CONVERT(VARCHAR,[id]),2)
+ RIGHT('000' + CONVERT(VARCHAR,SUM(CASE WHEN [type] = 'A' THEN 1 ELSE 0 END)),3)
+ RIGHT('000' + CONVERT(VARCHAR,SUM(CASE WHEN [type] = 'D' THEN 1 ELSE 0 END)),3)
+ RIGHT('000' + CONVERT(VARCHAR,SUM(CASE WHEN [type] = 'A' OR type = 'D' THEN 1 ELSE 0 END)),3)
FROM
[TRY]
GROUP BY
[id]

select result set row to columns transformation

I've a table remarks with columns id, story_id, like like can be +1, -1
I want my select query to return the following columns story_id, total, n_like, n_dislike where total = n_like + n_dislike without sub queries.
I am currently doing a group by on like and selecting like as like_t, count(like) as total which is giving me an output like
-- like_t --+ --- total --
-1 | 2
1 | 6
and returning two rows in result set. But what I want is to get 1 row where n_like is 6 and n_dislike is 2 and total is 8
First, LIKE is a reserved word in PostgreSQL, so you have to double-quote it. Maybe a better name should be picked for this column.
CREATE TABLE testbed (id int4, story_id int4, "like" int2);
INSERT INTO testbed VALUES
(1,1,'+1'),(1,1,'+1'),(1,1,'+1'),
(1,1,'+1'),(1,1,'+1'),(1,1,'+1'),
(1,1,'-1'),(1,1,'-1');
SELECT
story_id,
sum(CASE WHEN "like" > 0 THEN abs("like") ELSE 0 END) AS n_like,
sum(CASE WHEN "like" < 0 THEN abs("like") ELSE 0 END) AS n_dislike,
count(story_id) AS total
-- for cases +2 / -3 in the "like" field, use following construct instead
-- sum(abs("like")) AS total
FROM testbed
GROUP BY story_id;
I used abs("like") for cases when you'll have +2 or -3 in your "like" column.