Oracle Condition to Only Pull '0' Values - sql

I need to pull ID's with only 0 values for both A and B columns. An example:
+----+------+------+
| ID | A | B |
+----+------+------+
| 1 | null | 123 |
| 2 | 23 | 768 |
| 3 | 0 | 0 |
| 4 | 96 | 0 |
| 5 | 0 | null |
| 6 | 0 | 0 |
+----+------+------+
I have tried several queries, but I am still pulling through values above 0. As there are null values in the table, I have used the NVL(expr1,0) syntax to replace null with 0:
+----+------+------+
| ID | A | B |
+----+------+------+
| 1 | 0 | 123 |
| 2 | 23 | 768 |
| 3 | 0 | 0 |
| 4 | 96 | 0 |
| 5 | 0 | 0 |
| 6 | 0 | 0 |
+----+------+------+
I am using the following in my WHERE clause, and get the below results:
Where status = 'OPEN'
AND a.value IS NULL OR a.value = '0'
AND b.value IS NULL OR b.value = '0'
Output:
+----+----+-----+
| ID | A | B |
+----+----+-----+
| 1 | 0 | 123 |
| 3 | 0 | 0 |
| 5 | 0 | 0 |
| 6 | 0 | 0 |
+----+----+-----+
It seems as though I am pulling only 0 values for A, but I am still getting values above 0 for B. I need to only pull ID's with a value of 0 for both A and B.

I think you just need parentheses:
Where status = 'OPEN' AND
(a.value IS NULL OR a.value = 0) AND
(b.value IS NULL OR b.value = 0)

I like Gordon's answer, but I would use COALESCE here for brevity:
SELECT *
...
WHERE
status = 'OPEN' AND
COALESCE(a.value, 0) = 0 AND
COALESCE(b.value, 0) = 0;
We could also express using a sum:
WHERE
status = 'OPEN' AND
COALESCE(a.value, 0) + COALESCE(b.value, 0) = 0;

Related

T-SQL - subqueries on rows grouped by ID to create a summary table

I have a table "MyTable" with an id and two int fields "A" and "B":
MyTable
+-------+-----+-----+
| ID | A | B |
+-------+-----+-----+
| 99 | 0 | 1 |
| 99 | 0 | 1 |
| 99 | 0 | 0 |
| 99 | 1 | 1 |
| 99 | 0 | 1 |
| 100 | 1 | 0 |
| 100 | 0 | 0 |
| 100 | 0 | 0 |
| 444 | 1 | 0 |
| 88 | 0 | 0 |
| 88 | 0 | 0 |
| 88 | 0 | 1 |
+-------+-----+-----+
I'd like a T-SQL query to return a single row for each distinct id, which contains:
each distinct ID
whether there exists a row for that ID with a non-zero value for "a"
whether there exists a row for that ID with a non-zero value for "b"
like so:
+-------+-----+-----+
| ID | A | B |
+-------+-----+-----+
| 99 | 1 | 1 |
| 100 | 1 | 0 |
| 444 | 1 | 0 |
| 88 | 0 | 1 |
+-------+-----+-----+
I can GROUP BY the ID, but I don't know how to create the joins or subqueries on each group to get the desired result.
select id, max(case when A<>0 then 1 else 0 end)A, max(case when B<>0 then 1 else 0 end)B
from mytable
group by id
Or you can just use since your value is 1 and 0. But if value is other than that please use first query.
select id, max(A)A, max(B)B
from mytable
group by id

How to set value based on value existence in SQL Server?

I have the following T-SQL code:
select
id,
(case
when n in(Bla1', 'Bla2') then 1
when n = 'Bla3' then 99
else 0
end) as c
from
hello
Running this code outputs this result:
| id | c |
+--------+----+
| 577140 | 0 |
| 577140 | 1 |
| 577140 | 0 |
| 577140 | 0 |
| 577140 | 99 |
| 577141 | 0 |
| 577141 | 0 |
| 577141 | 0 |
| 577142 | 0 |
| 577142 | 0 |
| 577142 | 1 |
How can I modify the code to get the following output?
| id | c |
+--------+----+
| 577140 | 99 |
| 577141 | 0 |
| 577142 | 1 |
Rule
For each id: If 99 exists, then c becomes 99. If not, either 1 or 0, depending if any 1 exists.
You can use aggregation:
select id,
max(case when n in ('Bla1', 'Bla2') then 1
when n = 'Bla3' then 99
else 0
end) as c
from hello
group by id;

Presto SQL - Trying to pull data from multiple columns into one entry to find a unique, missing, or dupe entry

new to SQL/Presto here.
Feel free to point out the obvious if needed.
I have a sub query that pulls data into a table like below.
For each ItemID, 1 would mean that the tag is on, 0 is off.
I am trying to make a query that would pull up each ItemID with its associated tag if its unique, otherwise point out if there is more than one or if its missing.
Data_Table
| ItemID | TagA | TagB | TagC | TagD | TagE |
| 111 | 1 | 1 | 0 | 0 | 0 |
| 222 | 1 | 1 | 1 | 0 | 0 |
| 333 | 1 | 1 | 0 | 0 | 0 |
| 444 | 0 | 1 | 0 | 0 | 0 |
| 555 | 0 | 0 | 0 | 0 | 0 |
| 666 | 0 | 0 | 0 | 1 | 1 |
I tried a case when statement that pull each 1 and another case query that tries to convert each column into just one row entry.
SELECT Item_ID,
CASE WHEN (Tag_A+Tag_B+Tag_C+Tag_D+Tag_E > 1) THEN 'Dupe'
ELSE (CASE WHEN Tag_A = 1 THEN 'TagA_Present'
WHEN Tag_B = 1 THEN 'TagB_Present'
WHEN Tag_C = 1 THEN 'TagC_Present'
WHEN Tag_D = 1 THEN 'TagD_Present'
WHEN Tag_E = 1 THEN 'TagE_Present'
ELSE 'Missing_Tag' END)
END as ItemTag
FROM Data_Table
EDITED - I went too far with the sample data and initial query has been changed.
Actual Results
| ItemID | ItemTag |
| 111 | Dupe |
| 222 | TagA_Present |
| 333 | TagB_Present |
| 444 | TagB_Present |
| 555 | Missing |
| 666 | TagD_Present |
ItemID 111, 222, 333, and 666 should all be 'Dupe', but the results seems to be deeming random ones unique.
Hmmm. I am thinking:
select t.itemId,
(case when (TagA + TagB + TagC + TagD + TagE) > 1 then 'Dupe'
when TagA = 1 then 'TagA'
when TagB = 1 then 'TagB'
when TagC = 1 then 'TagC'
when TagD = 1 then 'TagD'
when TagE = 1 then 'TagE'
else 'Missing'
end) as ItemTag
from Data_Table;
There is no reason to use aggregation for this.

How to apply a NTILE function to a SQL column

So im trying to establish quantiles over the number of attentions received by some customers, but leaving NULLs and 0 out of the sample and placing them in the 0 and null quantil before applying NTILES function, I'm using this function:
CREATE FUNCTION dbo.RPS_Ntiles (#data int,#percentil int)
RETURNS TABLE
AS
RETURN
SELECT
NTILE(#percentil) OVER(ORDER BY #data DESC) as QUINTIL
WHERE #data > 0
UNION
SELECT
CASE
WHEN CONVERT(int,#data) = 0 THEN 0
WHEN #data is NULL THEN NULL
END AS QUINTIL
WHERE #data = 0 or #data = NULL
Then I'm applying it using CROSS APPLY
SELECT t.QUINTIL,D.[atenciones]
FROM table as D
CROSS APPLY [dbo].[RPS_NTiles](CONVERT(int,D.[atenciones]),5) as t
ORDER BY D.[atenciones] DESC
The result of this query is effective at leaving 0 and nulls out of the NTILEs function but the rest of the data is placed entirely in just 1 quintil like this:
+------------+---------+--+
| Atenciones | Quintil | |
+------------+---------+--+
| 0 | 0 | |
| 0 | 0 | |
| NULL | NULL | |
| 1 | 1 | |
| 3 | 1 | |
| 4 | 1 | |
| 7 | 1 | |
| 46 | 1 | |
| 59 | 1 | |
+------------+---------+--+
And I'm looking for something like this:
+------------+---------+--+
| Atenciones | Quintil | |
+------------+---------+--+
| 0 | 0 | |
| 0 | 0 | |
| NULL | NULL | |
| 1 | 1 | |
| 3 | 2 | |
| 4 | 2 | |
| 7 | 3 | |
| 46 | 4 | |
| 59 | 5 | |
+------------+---------+--+
Why define your own function? You can express this using case logic:
select (case when Atenciones is null or Atenciones = 0
then Atenciones
else ntile(5) over (partition by (case when Atenciones is null or Atenciones = 0 then 1 else 2 end)
order by Atenciones
)
end)

MySQL: Pivot + Counting

I need help with a SQL that will convert this table:
===================
| Id | FK | Status|
===================
| 1 | A | 100 |
| 2 | A | 101 |
| 3 | B | 100 |
| 4 | B | 101 |
| 5 | C | 100 |
| 6 | C | 101 |
| 7 | A | 102 |
| 8 | A | 102 |
| 9 | B | 102 |
| 10 | B | 102 |
===================
to this:
==========================================
| FK | Count 100 | Count 101 | Count 102 |
==========================================
| A | 1 | 1 | 2 |
| B | 1 | 1 | 2 |
| C | 1 | 1 | 0 |
==========================================
I can so simple counts, etc., but am struggling trying to pivot the table with the information derived. Any help is appreciated.
Use:
SELECT t.fk,
SUM(CASE WHEN t.status = 100 THEN 1 ELSE 0 END) AS count_100,
SUM(CASE WHEN t.status = 101 THEN 1 ELSE 0 END) AS count_101,
SUM(CASE WHEN t.status = 102 THEN 1 ELSE 0 END) AS count_102
FROM TABLE t
GROUP BY t.fk
use:
select * from
(select fk,fk as fk1,statusFK from #t
) as t
pivot
(COUNT(fk1) for statusFK IN ([100],[101],[102])
) AS pt
Just adding a shortcut to #OMG's answer.
You can eliminate CASE statement:
SELECT t.fk,
SUM(t.status = 100) AS count_100,
SUM(t.status = 101) AS count_101,
SUM(t.status = 102) AS count_102
FROM TABLE t
GROUP BY t.fk