in mysql:
Have data in data:
ColA | ColB | Rank
1 2 0
1 3 1
2 1 0
3 1 0
3 2 1
Keeping Col A as key field, need to get data on base of highest rank i.e.,
output:
ColA | ColB | Rank
1 3 1
2 1 0
3 2 1
any ideas..
You can do it this way:
SELECT T1.ColA, T2.ColB, T1.Rank
FROM TableName T2 JOIN
(SELECT ColA,MAX(Rank) as Rank
FROM TableName
GROUP BY ColA) T1 ON T1.ColA=T2.ColA AND T1.Rank=T2.Rank
Explanation:
Inner query (T1) selects records with highest rank for each values of ColA.
Outer query (T2) is used to select ColB with respect to the values of ColA and Rank from T2.
Result:
ColA ColB Rank
--------------------
1 3 1
2 1 0
3 2 1
See result in SQL Fiddle
Related
I would like your assistance in solving an issue which I am battling now for days without even coming close to a solution. Unfortunately, I have already posted my issue and was not able to make any improvement with the suggestion delivered.
What I would like to achieve is somewhat attained by GROUP BY and HAVING with the possibility of CASE WHEN but whatever I do I am not getting to what I desire.
What I want to achieve is a GROUP BY only when the contents of the group exceed 3 rows and leave the individual items i.e. not grouped when group is less than or equal to three.
EXAMPLE
ID DESC VAL1 VAL 2 VAL 3
1 DESC1 2 2 4
2 DESC2 2 2 4
3 DESC3 2 2 4
4 DESC4 2 2 4
5 DESC5 1 1 2
6 DESC6 1 1 2
GROUP BY will be through VAL1, VAL2, VAL 3 through the following
SELECT * FROM TABLE1 GROUP BY VAL1,VAL2,VAL3
This will yield the following:
ID DESC VAL1 VAL 2 VAL 3
1 DESC1 2 2 4
5 DESC5 1 1 2
However what I need is the following:
ID DESC VAL1 VAL 2 VAL 3
1 DESC1 2 2 4
5 DESC5 1 1 2
6 DESC6 1 1 2
Can this be achieved with GROUP BY, what I think of is subquery but I cannot manage. Your assistance will be very much appreciated.
DBMS is MySQL.
Try this one. It might require some minor tweaks, as I didn't test it. But i think you will get the idea.
Select *
from table1
where md5(concat(val1,val2,val3)) in (
SELECT md5(concat(val1,val2,val3))
FROM TABLE1
GROUP BY VAL1,VAL2,VAL3
having count(*) > 3)
group by VAL1,VAL2,VAL3
union
Select *
from table1
where md5(concat(val1,val2,val3)) not in (
SELECT md5(concat(val1,val2,val3))
FROM TABLE1
GROUP BY VAL1,VAL2,VAL3
having count(*) > 3)
With UNION ALL, for the 2 different cases:
select t.* from tablename t inner join (
select min(id) minid
from tablename
group by val1, val2, val3
having count(*) > 3
) g on g.minid = t.id
union all
select * from tablename t
where (
select count(*) from tablename
where val1 = t.val1 and val2 = t.val2 and val3 = t.val3
) <= 3
See the demo
If you are using MySQL 8.0, you can achieve this simply with window functions COUNT() and ROW_NUMBER():
SELECT id, descr, val1, val2, val3
FROM (
SELECT
t.*,
COUNT(*) OVER(PARTITION BY val1, val2, val3) cnt,
ROW_NUMBER() OVER(PARTITION BY val1, val2, val3 ORDER BY id) rn
FROM mytable t
) x WHERE cnt < 3 OR rn = 1
ORDER BY id
In the inner query, cnt indicates how many records have the same val1, va2, val3 as the current one. rn assigns a rank to each record within groups of records having the same val1, va2, val3. The outer query then uses these two pieces of information to filter the relevant records.
Demo on DB Fiddle:
| id | descr | val1 | val2 | val3 |
| --- | ----- | ---- | ---- | ---- |
| 1 | DESC1 | 2 | 2 | 4 |
| 5 | DESC5 | 1 | 1 | 2 |
| 6 | DESC6 | 1 | 1 | 2 |
I have a below table
id date1
1 1973-07-06
1 null
1 1994-01-20
1 1973-07-06
1 1980-03-12
1 1994-01-20
2 1960-10-17
2 1996-12-12
2 1996-12-12
2 2000-02-18
2 null
2 null
2 1960-10-17
2 1960-10-17
2 null
I need to find unique date1 value count for each id
Query i am using is as follows
select id,count(distinct date1) as col1
from iop
group by id
this query is giving me the wrong result as
id col1
1 4
2 4
However I should get
id col1
1 3
2 3
the query is counting the null value, try this:
select id,count(distinct date1) as col1
from iop
WHERE date1 NOT LIKE 'NULL'
group by id
My Table
colA | colB
0 | 0
1 | 0
0 | 1
1 | 1
if the values of colA and colB are different then count.
expected result: 2 (row 2 and row 3)
SELECT COUNT(*) as different
FROM tablename
WHERE colA != colB
I have a table which looks like this
userid | value | time
1 0 1
1 1 2
1 2 3
3 5 4
4 6 5
1 9 6
3 10 7
Using a select where in query I would want to select userd, value, and time but limit the total number of rows pulled for each userid
My SELECT query,
select userid, value, time from table where userid in (1,3) order by time desc;
This query outputs all the values like so
userid | value | time
1 0 1
1 1 2
1 2 3
3 5 4
3 10 7
I would hover want to limit the number of rows for each userid to two to get an output like so
userid | value | time
1 0 1
1 1 2
3 5 4
3 10 7
I tried using limit but that limits the number of rows for the entire output.
You can use a rank query to limit rows per user
select userid,
value,
`time`
from (
select *,
#r:= case when #g = userid then #r + 1 else 1 end row_num,
#g:=userid
from test t
cross join (select #g:= null,#r:=0) t1
where userid in (1,3)
order by userid,value,`time` desc
) t2
where row_num <= 2
Above query will give rank to each record for same user like user 1 has 3 records the they will assigned rank as 1,2,3 and if user 2 has 2 records then rank will be 1,2 for user 2 and in parent query i am just filtering the records according to the rank that return only result where rank is less than equal to 2 for for each user only 2 rows with rank 1 and 2 will be returned
Demo
I have two tables:
table1 table2
column id column id column value
1 1 count_20
2 1 count_30
3 2 count_20
4 2 count_50
... 2 count_200
3 count_30
3 count_50
3 count_200
4 count_130
... ...
I want to build a query that will select every row from table1, column id and the MAX value from the corresponding column value from table2 and make a DESC short as int in value column.
So the output should be:
table1.id value
2 count_200
3 count_200
4 count_130
1 count_30
... ...
I have tried JOIN but then, for every value (count_%) in table2 I get the corresponding id from table1.
SELECT table1.id, table2.id, table2.value FROM table1
LEFT JOIN table2
ON table2.id=table1.id
WHERE table1.id<'100'
ORDER BY
CASE value
WHEN 'count_20' THEN '20'
END DESC,
CASE value
WHEN 'count_30' THEN '30'
END DESC,
CASE value
WHEN 'count_50' THEN '50'
END DESC,
CASE value
WHEN 'count_130' THEN '130'
END DESC,
CASE value
WHEN 'count_200' THEN '200'
END DESC;
Output:
table1.id table2.id value
2 2 count_200
3 3 count_200
4 4 count_130
2 2 count_50
3 3 count_50
1 1 count_30
3 3 count_30
1 1 count_20
2 2 count_20
... ...
Any help would be appreciated.
Give this a try:
select t2.id,
'count_' + cast(max(cast(replace(t2.value, 'count_', '') as int)) varchar) intValue
from table1 t1
join table2 t2 on t1.id = t2.id
group by t2.id
order by max(cast(replace(t2.value, 'count_', '') as int)) desc
This results in:
+----+-----------+
| ID | VALUE |
+----+-----------+
| 2 | count_200 |
| 3 | count_200 |
| 4 | count_130 |
| 1 | count_30 |
+----+-----------+
Fiddle here.
http://www.w3schools.com/sql/sql_distinct.asp
check this out. this will only show the values onces.