I'm trying to create a query that'll update table_1 where column id_owner has more than 5 rows with the same owner id, it needs to set column "active" to 3 on all rows those users have.
I've tried several different methods and turned up empty with each. Any ideas?
Use this UPDATE query with JOIN to achieve this:
UPDATE table1 t1
JOIN
(
SELECT id_owner
FROM table1
GROUP BY id_owner
HAVING COUNT(*) > 5
) t2
ON t1.id_owner = t2.id_owner
SET t1.active = 3;
See this sample SQLFiddle
You may try this:-
update table_1
set active = 3
where owner_id in
(
select * from
(
select owner_id
from table_1
group by owner_id
having count(*) > 5
) a
)
update table_1
set active = 3
where owner_id in
(
select * from
(
select owner_id
from table_1
group by owner_id
having count(*) > 5
) x
)
SQLFiddle demo
Related
I have a table like given below name recomendation
I want to delete all the rows where cnt has the minimum value and there exist multiple records of ID_recipient.
If there is a single record of ID_recipient it shouldn't get deleted whatever the cnt value may be.
The ones highlighted in blue are the records that must stay.
I tried:
DELETE from table where(
SELECT DISTINCT(A.ID_recipient), DISTINCT(A.cnt) FROM (
SELECT MIN(cnt) as cnt FROM recomendation_table_ID_recipient GROUP BY ID_recipient HAVING COUNT(*) > 1 ) as A);
which is not working.
If you want to use 2 dimensions you have to use IN clause.
Your subquerys doesn't make much sense, so you should test this first, or post data with wanted example
DELETE from recomendation_table_ID_recipient where (ID_recipient,cnt) IN (
SELECT DISTINCT A.ID_recipient, A.cnt FROM (
SELECT ID_recipient, MIN(cnt) as cnt FROM recomendation_table_ID_recipient GROUP BY ID_recipient HAVING COUNT(*) > 1 ) as A);
delete t1 from recomendation_table_ID_recipient t1 join (
select ID_recipient, min(cnt) as cnt from recomendation_table_ID_recipient
group by ID_recipient
having count(*) > 1
) t2 on t1.ID_recipient = t2.ID_recipient and t1.cnt = t2.cnt;
See db-fiddle
My requirement is to get id based on latest frame (based on date-time) is inserted with group by vehicle id.
I have tried with below query
select a.id,a.vehicle_id,a.info_datetime
from table_name a
join (select id, max(info_datetime) as maxdt from table_name group by vehicle_id) as b
on a.info_datetime = b.maxdt
The output will not give the proper id.
So, I want the id for latest frame inserted with group by vehicle_id.
Max(id) or Max(info_datetime) query will not give the accurate result.
SELECT id, vehicle_id FROM table_name as a WHERE info_datetime =
(SELECT MAX(info_datetime) FROM table_name as b WHERE a.vehicle_id = b.vehicle_id)
GROUP BY vehicle_id
Your attempt is almost there, but you need to join by id as well:
select a.id,a.vehicle_id,a.info_datetime
from table_name a
join (
select vehicle_id, max(info_datetime) as maxdt from table_name group by vehicle_id
) as b on a.info_datetime = b.maxdt and a.vehicle_id = b.vehicle_id
Another way to do it is to filter with a correlated subquery:
select a.*
from table_name a
where a.info_datetime = (
select max(b.info_datetime) from table_name b where b.vehicle_id = a.vehicle_id
)
Finally got the solution for above.
SELECT id, vehicle_id, info_datetime
FROM table_name
WHERE id in (
select max(m2.id) from table_name m2 group by m2.vehicle_id)
ORDER BY vehicle_id asc,info_datetime DESC
It will take approx 2 to 3 seconds to execute in around 25 lac records.
I have these rows
user_id code
1 9103
1 9103
1 9001
2 9103
3 9103
3 9104
4 9103
4 9103
4 9001
I want to get only id that not contains 9001, then only 2 and 3
I try with Distinct But I without lucky
Select distinct v.code, user_id from mytable as v
where v.code not in ( Select v2.code from mytable as v2
where v2.code=9001)
Group by the user and then take only those groups having no record of the condition
select user_id
from your_table
group by user_id
having sum(code = 9001) = 0
There are multiple methods to get the results you need.
NOT EXISTS (ALL DBMS)
SELECT
*
FROM
Table1
WHERE
NOT EXISTS (
SELECT
1
FROM
Table1
WHERE
code = 9001
)
NOT IN (ALL DBMS)
SELECT
DISTINCT
Table1.user_id
FROM
Table1
WHERE
user_id NOT IN (
SELECT
user_id
FROM
Table1
WHERE
code = 9001
)
RIGHT JOIN / LEFT JOIN (ALL DBMS but for example SQLite does not support RIGHT JOIN)
SELECT
DISTINCT
Table1.user_id
FROM (
SELECT
user_id
FROM
Table1
WHERE
code = 9001
) AS Table1_filter
RIGHT JOIN
Table1
ON
Table1_filter.user_id = Table1.user_id
WHERE
Table1_filter.user_id IS NULL
;
SELECT
DISTINCT
Table1.user_id
FROM
Table1
LEFT JOIN (
SELECT
user_id
FROM
Table1
WHERE
code = 9001
) AS Table1_filter
ON
Table1_filter.user_id = Table1.user_id
WHERE
Table1_filter.user_id IS NULL
;
Conditional SUM (#juergen d answer) (ALL DBMS)
SELECT
Table1.user_id
FROM
Table1
GROUP BY
Table1.user_id
HAVING
SUM(Table1.code = 9001) = 0
Variation on (#juergen d answer) with GROUP_CONCAT (MySQL and SQLite only)
Also possible with
... HAVING FIND_IN_SET('9001', GROUP_CONCAT(Table1.code)) = 0 (MySQL Only)
SELECT
Table1.user_id
FROM
Table1
GROUP BY
Table1.user_id
HAVING
GROUP_CONCAT(Table1.code) NOT LIKE '%9001%'
p.s GROUP_CONCAT(Table1.code) NOT LIKE '%9001%' might also select false positives depending on the data used. Using FIND_IN_SET('9001', GROUP_CONCAT(Table1.code)) = 0 is more safe option to use.
see demo http://sqlfiddle.com/#!9/fc6f6b/34
I have a table
id = 1
name = 'one'
group = 1
id = 2
name = 'two'
group = 1
id = 3
name = 'three'
group = 2
and i have to get in one sql query all names which are singles, in this case id = 3
and another sql all names which are multiples, in this case id=1 and id=2, since they have the same group.
I suppose it should be a select in select but not sure.
Thanks in advance.
It sounds like you want to use something similar to this:
select id
from yourtable
group by `group`
having count(`group`) = 1
See SQL Fiddle with Demo.
Then if you want to return all details, then you can expand the query to:
select *
from yourtable t1
where id in (select id
from yourtable t2
group by `group`
having count(`group`) = 1)
See SQL Fiddle with Demo.
If you want to return all rows that have the same group, then you can use:
select *
from yourtable t1
where `group` in (select `group`
from yourtable t2
group by `group`
having count(`group`) > 1)
See SQL Fiddle with Demo
Then if you want to return everything and a flag that identifies if it is a single or multiple, then you can use something similar to this. You will notice that I included a flag to show what groups have one row and then what groups have more than one row:
select *, 'single' Total
from yourtable t1
where `group` in (select `group`
from yourtable t2
group by `group`
having count(`group`) = 1)
union all
select *, 'multiple' Total
from yourtable t1
where `group` in (select `group`
from yourtable t2
group by `group`
having count(`group`) > 1)
See SQL Fiddle with Demo
I know this sounds rather confusing but I'm at a loss how to explain it better. I have a table simplified below:
DB Type ID
================
Table1 1
Table1 2
Table1 3
Table1 4
Table1 5
Table2 6
Table2 7
Table2 8
Table2 9
Table2 10
what i am trying to achieve is to basically clean out this table but keep the record with the highest ID for each DB Type if that makes sense - so in this case it would be (Table1,5) and (Table2,10) with all other records being deleted. Is it possible to do this exclusively through MySQL?
*EDIT***
Answer thanks to tips from Yogendra Singh
DELETE FROM MyTable WHERE ID NOT IN (SELECT * FROM (SELECT MAX(ID) from MyTable GROUP BY DB Type) AS tb1 ) ORDER BY ID ASC
TRY selecting the max ID group by db_type first and then use it as sub query with not in.
DELETE FROM MyTable
WHERE ID NOT IN
(SELECT ID FROM
(SELECT MAX(ID) AS ID from MyTable GROUP BY DB Type) AS tb1
)
EDIT:
DELETE FROM MyTable
HAVING MAX(ID) > ID;
delete your_table
from
your_table left join
(select max(id) max_id from your_table group by type) mx
on your_table.id=mx.max_id
where mx.max_id is null
Subquery returns the maximum id for every type, and those are the values to keep. With an left join i'm selecting all the rows from your table that don't have an in in max_ids, and those are the rows to delete. This will work only if id is primary key, otherwise we have to join also the type.
Is the combination DB Type - ID unique?
If so, you can attack this in two stages:
Get only the rows you want
SELECT [DB Type], Max(ID) AS MaxID
FROM YourTable
GROUP BY [DB Type]
Delete the rest (Wrapping the previous statement into a more complicated statement; don't mean that)
DELETE FROM YourTable
FROM
YourTable
LEFT JOIN
(SELECT [DB Type], Max(ID) AS MaxID
FROM YourTable GROUP BY [DB Type]) DontDelete
ON
YourTable.[DB Type]=DontDelete.[DB Type] AND
YourTable.ID=DontDelete.MaxID
WHERE
DontDelete.[DB Type] IS NULL
DELETE FROM MyTable del
WHERE EXISTS (
(SELECT *
FROM MyTable xx
WHERE xx."db Type" = del."db Type"
AND xx.id > del.id
);
delete from my_Table
where Day in (select MAX(day) d from my_Table where id='id')