Find records only all value are same in column otherwise return 0 - sql

I have the following table
id
name
1
Gaurav
1
Ram
1
Gaurav
1
Gaurav
From the above table I want to fetch records if name have same value as Gaurav. For example one row has name Ram so it should not return any thing. If all value is Gaurav then return id.

On MySQL, you could use aggregation:
SELECT id
FROM yourTable
GROUP BY id
HAVING SUM(name = 'Gaurav') = COUNT(*);
On all databases:
SELECT id
FROM yourTable
GROUP BY id
HAVING COUNT(CASE WHEN name = 'Gaurav' THEN 1 END) = COUNT(*);

You can try this as well. Bit hardcoded. You can use 0 instead of null and remove where clause as well if you want.
SELECT Case When Name ='Gaurav' Then ID else NULL END AS ID
FROM Yourtable
where name ='Gaurav'

Related

BigQuery(standard SQL) grouping values based on first CASE WHEN statement

Here is my query with the output below the syntax.
SELECT DISTINCT CASE WHEN id = 'RUS0261431' THEN value END AS sr_type,
COUNT(CASE WHEN id in ('RUS0290788') AND value in ('1','2','3','4') THEN respondentid END) AS sub_ces,
COUNT(CASE WHEN id IN ('RUS0290788') AND value in ('5','6','7') THEN respondentid END) AS pos_ces,
COUNT(*) as total_ces
FROM `some_table`
WHERE id in ( 'RUS0261431') AND id <> '' AND value IS NOT NULL
GROUP BY 1
As you can see with the attached table I'm unable to group the values based on Id RUS0290788 with the distinct values that map to RUS0261431. Is there anyway to pivot with altering my case when statements so I can group sub_ces and pos_ces by sr_type. Thanks in advanceenter image description here
You can simplify your WHERE condition to WHERE id = ('RUS0261431'). Only records with this value will be selected so you do not have to repeat this in the CASE statements.

Querying a subset

I want to write an SQL query to find records which contain a particular column and from that subset want to find records which doesn't contain a some other value. How do you write a query for that?
cid id2 attribute
--------------------------------
1 100 delete
1 100 payment
1 100 void
2 100 delete
2 102 payment
2 102 void
3 102 delete
3 103 payment
In above example, I want to list cid for which payment and delete attributes exist but void attribute doesn't exist. So it should list out 3 from above example because it doesn't have void attribute.
Forgot to mention that there could be more attributes. However, I need to list out records for which delete and payment exist regardless of other attributes but void doesn’t.
I call this a "set-within-sets" query, because you are looking for particular sets of attributes within each cid.
I would express this with group by and conditions in the having:
select cid
from t
group by cid
having sum(case when attribute = 'payment' then 1 else 0 end) > 0 and
sum(case when attribute = 'delete' then 1 else 0 end) > 0 and
sum(case when attribute = 'void' then 1 else 0 end) = 0 ;
In some databases, you can simplify this with string aggregation -- assuming there are no duplicate attributes for cids. For instance, using the MySQL function:
select cid
from t
where attribute in ('payment', 'delete' 'void')
group by cid
having group_concat(attribute order by attribute) = 'delete,payment';
You can use conditional aggregation:
select cid
from tablename
where attribute in ('delete', 'payment', 'void')
group by cid
having
count(distinct attribute) = 2
and
sum(
case attribute
when 'void' then 1
else 0
end
) = 0
If there are not more attributes than these 3, then you can omit the WHERE clause.
See the demo.
Results:
| cid |
| --- |
| 3 |
I'm assuming that there are only three attributes, so the logic behind this query is:
First COUNT the number of attributes GROUP BY cid, and then LEFT JOIN the original table ON attribute is void. You should grab cid that has exactly 2 attributes and no void.
The original table is named as temp:
SELECT
subq2.result_cid
FROM (
SELECT
*
FROM (
SELECT
T.cid AS result_cid,
COUNT(T.attribute) AS count
FROM
temp AS T
GROUP BY
T.cid
) AS subq
LEFT OUTER JOIN temp AS T2 ON subq.result_cid = T2.cid AND T2.attribute = 'void'
) AS subq2
WHERE subq2.count = 2 AND subq2.id2 IS NULL
use corelated subquery by using not exists
select t1.* from tablename t1
where not exists( select 1 from tablename t2
where t1.cid=t2.cid and attribute='void'
)
and exists ( select 1 from tablename t2
where t1.cid=t2.cid
having count(distinct attribute)=2
)
and attribute in ('payment','delete')
demo online

Selecting a group with or without certain conditions across many rows in SQL

I have data like this:
ID SomeVar
123 0
123 1
123 2
234 1
234 2
234 3
456 3
567 0
567 1
I'm trying to group by my ID to to return all of the IDs that do not have a record with the value 0. That is, my selection would look like this:
ID
234
456
Is there an easy way to do this without creating a subset table with all records not containing 0 then joining it back to the full data set where the tables don't match?
I generally try to avoid subqueries, but you could use one for this case. Do the same group by, and check that the id isn't in a subquery of ids that have 0 for SomeVar. In this case, distinct will do the same and more efficiently, so I'll do that first:
SELECT DISTINCT ID
FROM [table_name]
WHERE ID NOT IN (
SELECT ID FROM [table_name] WHERE SomeVar = 0
);
And if you want to get other information by using a GROUP BY:
SELECT ID, max(SomeVar), count(*), sum(SomeVar)
FROM [table_name]
WHERE ID NOT IN (
SELECT ID FROM [table_name] WHERE SomeVar = 0
)
GROUP BY ID;
You can use aggregation and having:
select id
from t
group by id
having min(somevar) > 0;
This assumes that somevar is never negative. If that is a possibility, then you can use the slightly more verbose:
select id
from t
group by id
having sum(case when somevar = 0 then 1 else 0 end) = 0;
Use case statement with count or sum aggregation, filter by count using having:
select ID
from
(
select ID, count(case when SomeVar=0 then 1 end) cnt
from mytable
group by ID having count(case when SomeVar=0 then 1 end) = 0
) s
;

listagg in SQL to group rows in to one row

i have a table 1 shown below
Name role F1 status1 status 2
sam player yes null null
sam admin yes null null
sam guest no x x
i want the result to be
Name role status1 status 2
sam admin,player x x
i have done a query to list_agg the role in to one row.but the status is null for sam to show when F1='yes'
query i used
select name,list_agg(role,',') within group(order by name),max(status1),max(status2)
from table 1 where F1='yes'
group by name
but i get something like this
name role status1 status2
sam admin,player null null
i want the where to work only on role column and the max(status1) to be in status1 i.e.'x'.please help me .thank you
You can try using LISTAGG() within a GROUP BY query:
SELECT Name,
LISTAGG(Role, ',') WITHIN GROUP (ORDER BY Role) "Role"
MAX(CASE WHEN water_access = 'Y' THEN 'Y' ELSE NULL END) "water_access",
MAX(CASE WHEN food_access = 'Y' THEN 'Y' ELSE NULL END) "food_access",
MAX(CASE WHEN power_access = 'Y' THEN 'Y' ELSE NULL END) "power_access"
FROM yourTable
GROUP BY Name
ORDER BY Name DESC
Note that I chose to order the aggregation of each Name group using the Role, because you didn't provide us with any column which could give the ordering you show in your expected output.
Second note: MAX() in Oracle ignores NULL values, so it can be used in the pivot to correctly identify the Y values you want to appear.
try this out...
select * from table_name pivot(sum(name) for role

SQL CASE SUBQUERY COUNT

I have table with 2 col :
UID NAME
-----------
111 AAA
222 BBB
Customer will enter the name and I have to retrieve UID with respective value. If name won't present in the rows, it has to retrieve 000, not like no rows.
I am trying to write query like this:
SELECT
CASE UID
WHEN Count(*) = 0 THEN '000'
ELSE UID
END
FROM table1
WHERE NAME ='XXX'
Please help me in this regard. Thanks in advance...
If UID is an integer, then you need to take casts into account:
select coalesce(cast(max(uid) as char(3)), '000')
from table1
where name = 'XXX'
The cast is intended to be to the type of UID, which seems to be char(3) in your example.
When there are no matching rows, then the max() function returns NULL. The coalesce() turns this into the value you are looking for.
try this
select case
when max(id) is null then
0
else
max(id)
end
from table1
where name = 'b'
You have error in case
SELECT case when count(UID) = 0 THEN '000' ELSE UID end FROM table1 where name = 'XXX'
sqlfiddle :http://www.sqlfiddle.com/#!2/257ea/1