I Have below mentioned table:
ID Value
U-1 ACB
U-1 ART
U-1 DDD
U-2 ACB
U-2 DDD
U-3 XCC
U-3 DFC
I want to fetch those rows where Value is DDD but total count of unique ID is <3.
Required Output:
ID Value
U-2 ACB
U-2 DDD
You could use a self join to same table, Inner query will calculate count per id and filter rows where count is less than 3
select a.*
from table1 a
join (
select id, count(*) total
from table1
group by id
having total < 3
and sum(`Value` = 'DDD') > 0
) t using(id);
Demo
OR
select a.*
from table1 a
where (
select count(*)
from table1
where ID = a.ID
having sum(`Value` = 'DDD') > 0
) < 3
but i prefer join approach
updated demo
How about this?
SELECT * FROM
(SELECT * FROM sof t1
WHERE (SELECT COUNT(id) FROM sof t2 WHERE t2.id = t1.id) < 3) as temp2
WHERE id IN (SELECT id FROM sof WHERE value = 'DDD')
The input and output matches for your case at my end atleast.
Demo: http://rextester.com/AZLA7822
Related
cust_id
state
1
CA
2
IL
3
SC
1
PA
3
IA
4
MO
5
VA
4
NY
Can any one please advise on SQL Query that return the cust_id that belong to two states as below:
The output should be
cust_id
state
1
CA
1
PA
3
SC
3
IA
4
NY
4
MO
Try the following query
Solution 1
Select * From yourtable
Where Cust_Id In (Select cust_id From yourtable Group By cust_id Having
Count(*) = 2) Order By cust_id,state
Solution 2
With T1 As
(Select cust_id From yourtable Group By cust_id Having Count(*) = 2)
Select T2.* From yourtable T2 Join T1 On T1.cust_id = T2.cust_id O
Order By T2.cust_id,T2.state
SELECT tmp.*
FROM tmp
INNER JOIN (
SELECT cust_id
,COUNT(STATE) s_count
FROM tmp
GROUP BY [cust_id]
) sub
ON tmp.cust_id = sub.cust_id
WHERE sub.s_count = 2
ORDER BY cust_id
,STATE
One simple approach would use a COUNT window function, that will assign the amount of times each "cust_id" occurs in your table. Once you get this value, you can filter out rows whose count is smaller than 2.
WITH cte AS (
SELECT *, COUNT(cust_id) OVER(PARTITION BY cust_id) AS cnt
FROM tab
)
SELECT cust_id,
state
FROM cte
WHERE cnt > 1
Check the demo here.
Sorry for the poor formatting but as part of a larger problem, I have created a query that produces this table:
id id2
4 7
4 6
1 3
1 2
1 1
How would I extract the rows that don't have the highest id2 for each id1.
What I want:
id id2
4 6
1 2
1 1
I can only seem to figure out how to get rid of the max id2 overall but not for each distinct id1. Any help on actually differentiating the max id2 for each id1 would be appreciated.
You can try below way -
select a.id, a.id2
from tablename a
where a.id2 <> (select max(a1.id2) from tablename a1 where a.id=a1.id)
If you are using MySQL 8+, then RANK() provides one option:
WITH cte AS (
SELECT id, id2, RANK() OVER (PARTITION BY id ORDER BY id2 DESC) rnk
FROM yourTable
)
SELECT id, id2
FROM cte
WHERE rnk > 1
ORDER BY id DESC, id2 DESC;
Demo
instead of a correlated subquery in the where, you can LEFT JOIN and apply not in...
select id, id2
from yourTable YT
LEFT JOIN
( select id, max( id2 ) highestID2
from YourTable
group by id ) TopPerID
on YT.ID = TopPerID.ID
AND YT.ID2 != TopPerID.highestID2
where TopPerID.id IS NULL
Since you can have id values with only one id2 value, you need to check for that situation as well, which you can do by comparing the MAX(id2) value with the MIN(id2) value in a JOIN:
SELECT t1.*
FROM Table1 t1
JOIN (SELECT id, MAX(id2) AS max_id2, MIN(id2) AS min_id2
FROM Table1
GROUP BY id) t2 ON t2.id = t1.id
AND (t1.id2 < t2.max_id2 OR t2.min_id2 = t2.max_id2)
If we add a row 2, 5 to your sample data this correctly gives the result as
id id2
4 6
1 2
1 1
2 5
Demo on SQLFiddle
I have three select statements as follows and I would like to sum up total number of records. How can I do that?
SELECT COUNT(*) AS Number FROM tableA where user_id = 5 //Total 5 records
SELECT COUNT(*) AS Number FROM tableB where user_id = 5 //Total 6 records
SELECT COUNT(*) AS Number FROM tableC where user_id = 5 //Total 1 records
so return result will be 12.
You could apply count(*) to the result of a union all:
SELECT COUNT(*)
FROM (SELECT user_id FROM tablea
UNION ALL
SELECT user_id FROM tableb
UNION ALL
SELECT user_id FROM tablec) t
WHERE user_id = 5
I think this should do the trick:
SELECT SUM(Number)
FROM (
SELECT COUNT(*) AS Number FROM tableA where user_id = 5
UNION ALL
SELECT COUNT(*) AS Number FROM tableB where user_id = 5
UNION ALL
SELECT COUNT(*) AS Number FROM tableC where user_id = 5
)
select ( select count(*) from tableA where user_id = 5 )
+ ( select count(*) from tableB where user_id = 5 )
+ ( select count(*) from tableC where user_id = 5 )
as total_rows
from dual
I have records like this....
oid id
35 1
43 1
46 1
43 2
49 2
50 3
51 3
52 4
I have id=1 and 2 . I want those results which belong to both the both the ids(1,2) only.
i.e - o/p = recodrds of object_id = 43 because it is belonging to both 1 and 2.
if I use in operator then it is giving all the records (performing OR operaion)
This is a generic, fast solution to this kind of problems.
Get all IDs (in this case oid values) that staisfy our condition:
select oid from MyTalbe
where id in (1,2)
group by oid
having count (distinct id) >1
Select rows where IDs ('oid` column) IN list of IDs we need:
select oid, id from Mytable
where oid in
(select oid from MyTalbe
where id in (1,2) -- This is the same as: where id =1 or id=2
group by oid
having count (distinct id) >1
)
You can use the IN operator but then use a GROUP BY with a HAVING clause to return only those rows with a DISTINCT count of 2:
select oid
from yourtable
where id in (1,2)
group by oid
having count(distinct id) = 2;
--^ change this number to the count of ids in IN clause
See SQL Fiddle with Demo
Try this
SELECT t.oid FROM table1 t
WHERE t.oid IN (SELECT oid FROM table1 t1 WHERE t1.oid=t.oid AND t1.id = 1)
AND t.oid IN (SELECT oid FROM table1 t1 WHERE t1.oid=t.oid AND t1.id = 2)
GROUP BY oid
I have a table:
ID CLUSTERID
1 56
1 24
1 24
1 35
2 13
2 24
Now, i want to get the following:
I want to count per id, which cluster id repeats most of the time.
For example, in ID=1, CLUSTERID=24 repeats most of the time
In ID=2 i have 2 CLUSTER IDs that repeats the same.
So in the output i will have:
ID CLUSTERID
1 24
2 13
2 24
The answer that i wrote (and works)
TT is my original table that have 2 columns: ID and CLUSTER ID
SELECT t3.ID,t3.ClusterID,t3.ListingAmount
FROM
(SELECT ID, ClusterID, COUNT() AS ListingAmount
FROM tt
GROUP BY ID, ClusterID) AS t3 LEFT JOIN
(SELECT ID, MAX(ListingAmount) AS amount
FROM
(SELECT ID, ClusterID, COUNT() AS ListingAmount
FROM tt
GROUP BY ID, ClusterID) AS t2
GROUP BY ID) AS BB ON BB.id=t3.id
WHERE BB.amount=t3.ListingAmount
Can't think of a more elegant solution right now (I'm sure there is), but it seems to do the job:
select t1.id,
t1.clusterid,
t1.cnt
from (
select id,
clusterid,
count(*) as cnt
from foo
group by id, clusterid
) t1
join (select id,
max(cnt) as max_count
from (
select id,
clusterid,
count(*) as cnt
from foo
group by id, clusterid
) tm
group by id
) t2 on t1.id = t2.id
and t1.cnt = t2.max_count
order by t1.id, t1.cnt;
SQLFiddle example: http://sqlfiddle.com/#!2/2cacc/3