ID GRP VAL CHK
--- ----- ----- ----
1 1 1 0
2 1 3 0
3 2 7 0
4 2 2 0
5 2 1 0
6 3 5 0
I want to set my CHK field to '1' having maximum value VAL for every group of GRP,
so ID 2,3,6 should be set.
I don't write my trials here, all seems rubbish :)
In MySQL, you can do this using the update/join syntax:
update table t join
(select grp, max(val) as maxval
from table t
group by grp
) tmax
on t.grp = tmax.grp and t.val = tmax.maxval
set t.chk = 1;
Related
I have sample Data Set
ID Name Active
1 Mii 0
1 Mii 1
2 Rii 0
2 Rii 1
3 Lii 0
4 Kii 0
4 Kii 1
5 Sii 0
How I can get active records along with Inactive records for other ID's.
ID Name Active
1 Mii 1
2 Rii 1
3 Lii 0
4 Kii 1
5 Sii 0
I have taken all the data into 2 temp tables because lot of joins are there
select * from tmp1 where active = 1
UNION ALL
select * from tmp2 where active = 0 AND
NOT EXISTS (SELECT 1 FROM tmp1 WHERE Active = 1 )
can anyone tell me is there any better way to write in MYSQL
Assuming that active can only be 0 or 1, aggregation could help:
SELECT id,
name,
max(active) active
FROM elbat
GROUP BY id,
name;
max(active) is 1, if there is a record with the id and name that has a 1 in active, as 1 > 0. Otherwise it is 0, the only value.
Using analytical functions:
select * from (
SELECT ID, NAME, RANK() OVER ( ORDER BY ACTIVE desc) AS RN
FROM TABLE1) a where rn = 1;
I've a table:-
id value
1 1
1 2
1 1
1 4
2 1
2 3
2 2
3 1
4 2
I want to get the id and their respective count having value = 1, ie For the above table, the output should be the following:-
id count
1 2
2 1
3 1
4 0
Since, id = 1 has 2 entries of 1, id = 2 has 1 entry of 1, similarly id 3 has 1 entry, id 4 has 0 entry.
I'm get the following output using the following que:-
select id,count(value)
from table
where value=1
group by id
order by count(value);
id count
1 2
2 1
3 1
I want to get the 4, 0 entry as well. How can I do that?
Try this
select id,sum(case when value ='1' then 1 else 0 end) as val
from table
group by id
order by id;
You try this Sql Query
select id,COUNT(CASE WHEN value = '1' THEN 1 END) count
from tablename
group by id;
It is the where clause that remove the row id=4
try following:
select id,sum(case when value = 1 then 1 else 0 end) as count
from table
group by id
order by sum(case when value = 1 then 1 else 0 end);
I have table:
id date default(bool)
1 2015-01-01 0
2 2015-01-02 0
3 2015-01-03 1
4 2015-01-04 1
5 2015-01-05 1
6 2015-01-06 0
7 2015-01-07 0
8 2015-01-08 1
9 2015-01-09 1
10 2015-01-10 0
I want only rows where ordered by date rows change default column from 0 to 1, so in this table rows: 3 and 8.
If id can be used instead of date, use a correlated sub-query to read previous row's value:
select *
from tablename t1
where default = 1
and (select default from tablename t2
where t2.id = t1.id - 1) = 0
Use date instead to find previous row:
select *
from tablename t1
where default = 1
and (select default from tablename t2
where t2.date = (select max(date) from tablename
where date < t1.date)) = 0
Here is another way using dynamic variable
select t.id,t.date,t.`default`
from (
select
t1.*,
#default := if(#prev_default = 0 and t1.`default` = 1,1,0) as def,
#prev_default:=t1.`default`
from (
select * from test order by date
)t1,
(select #prev_default:= 2,#default:=0)r
)t
where t.def = 1 ;
Here is my table with sample data:
id|group_id|column1|column2|column3|
--------------------------------------
1 1 | 1 1 0
2 1 | 1 1 1
3 2 | 0 0 0
4 2 | 1 1 1
5 1 | 1 0 0
6 3 | 0 0 0
Expected result set: (The result should show the maximum sum (col 1 + col 2 + col 3) in each group)
id|group_id|column1|column2|column3|
--------------------------------------
2 1 | 1 1 1
4 2 | 1 1 1
6 3 | 0 0 0
Actual result set: (select *, max(m.column1 + m.column2 + m.column3) as total from my_table m group by m.group_id) which is wrong
id|group_id|column1|column2|column3|total|
------------------------------------------
1 1 | 1 1 0 3
3 2 | 0 0 0 3
6 3 | 0 0 0 0
I'm quite new to SQL, it seems like the query selecting the first id in each group.
what is the best way to get expected result?
You can do get your desired result i.e. with a subselect:
First step:
SELECT
MAX(m1.column1 + m1.column2 + m1.column3)
FROM
my_table m1
GROUP BY
m1.group_id
will get you the maximum total per group_id.
Because values in non aggregated columns are indetermined, if this columns contains different values for a group, you can't simply aggregate as you've done, but a subselect using the query from first step will do it:
Complete query
SELECT
*,
m.column1 + m.column2 + m.column3 as total
FROM
my_table m
WHERE
m.column1 + m.column2 + m.column3 = (
SELECT
MAX(m1.column1 + m1.column2 + m1.column3)
FROM
my_table m1
WHERE
m.group_id = m1.group_id
GROUP BY
m1.group_id
);
Demo
Looks like you are trying to get the rows that yield highest sum of 3 columns in each group:
select a.*
from my_table a
join (
select group_id, max(column1 + column2 + column3) summation
from my_table
group by group_id) b on a.group_id = b.group_id and a.column1 + a.column2 + a.column3 = b.summation;
You didn't specified exactly which values for column1, column2 and column3 must be returned.
select m.*,n.* from
m,
(select
group_id as n_group_id,
max(column1+column2+column3) as n_total
from m group by group_id) as n
where m.group_id=n_group_id and (column1+column2+column3)=n_total
I am writing a query to grab the items that a specific user_id was the first to use. Here is some sample data -
item_id used_user_id date_used
1 1 2012-08-25
1 2 2012-08-26
1 3 2012-08-27
2 2 2012-08-27
3 1 2012-08-27
4 1 2012-08-21
4 3 2012-08-24
5 3 2012-08-23
query
select item_id as inner_item_id, ( select used_user_id
from test
where test.item_id = inner_item_id
order by date_used asc
limit 1 ) as first_to_use_it
from test
where used_user_id = 1
group by item_id
It returns the correct values
inner_item_id first_to_use_it
1 1
3 1
4 1
but the query is VERY slow on a giant table. Is there a certain index that I can use or a better query that I can write?
i can't get exactly what you mean because in your inner query you have sorted it by their used_user_id and and on your outer query you have filtered it also by their userid. Why not do this directly?
SELECT DISTINCT item_id AS inner_item_id,
used_user_id AS first_to_use_it
FROM test
WHERE used_user_id = 1
UPDATE 1
SELECT b.item_id,
b.used_user_id AS first_to_use_it
FROM
(
SELECT item_ID, MIN(date_used) minDate
FROM tableName
GROUP BY item_ID
) a
INNER JOIN tableName b
ON a.item_ID = b.item_ID AND
a.minDate = b.date_used
WHERE b.used_user_id = 1