How could I run the following query in rake task ?
DELETE FROM crawled_categories WHERE id NOT IN (
SELECT id FROM (
SELECT DISTINCT(site_id, parent_category, breadcrumb), max(id) AS id
FROM crawled_categories
WHERE map_id is null
GROUP BY site_id, parent_category, breadcrumb
) AS tmp
) AND map_id IS NULL
I tried the following code and it worked fine :
ActiveRecord::Base.connection.execute("DELETE FROM crawled_categories WHERE id NOT IN ( SELECT id FROM ( SELECT DISTINCT(site_id, parent_category, breadcrumb), max(id) AS id FROM crawled_categories WHERE map_id is null GROUP BY site_id, parent_category, breadcrumb ) AS tmp ) AND map_id IS NULL")
Related
I want to delete it for the output to look like this. In one group there should be only 1 user_id.
select distinct group_id, user_id, count(*)
from pin_users
where group_id in (select group_id from pin_users)
group by group_id, user_id
having count(*) > 1
I get all user_id, group_id and count more than 1 but I don't know how to delete duplicates and leave only 1 left.
Ps. My English is probably not perfect, pls excuse any mistakes
Make a subquery to get a list of minimum ids for any combination of users and groups. Then remove everything else.
DELETE FROM pin_users WHERE id NOT IN (
SELECT min(id) as id
FROM pin_users
GROUP BY group_id, user_id
)
In case of sql-server, try this:
-- mockup data
declare #Raw table (
id nvarchar(max),
group_id nvarchar(max),
user_id nvarchar(max)
)
insert into #Raw values ('p001', 'aaa', 'ava001'), ('p002', 'aaa', 'ava001'), ('p003', 'bbb', 'ava001'), ('p004', 'bbb', 'ava001');
-- check this query
with A as (
select id, ROW_NUMBER() over(partition by group_id, user_id order by id) as RN
from #Raw)
delete from #Raw where id in (select id from A where A.RN > 1)
-- verify table
select * from #Raw
For example, with sql server should be something like this
delete u1
from pin_users u1
join (
select min(id) id, group_id, user_id
from pin_users
group by group_id, user_id
) u2
on u1.group_id = u2.group_id
and u1.user_id = u2.user_id
and u1.id <> u2.id
I want to take the result of a CTE query and use it inside another query.
This simplified example uses a CTE query to return a list of ids.
with test_cte (id,name) as (
select id, name
from test
)
select id
from test_cte
where name = 'john'
I want to use this list of ids to delete some records like this but I'm getting a syntax error:
delete from test
where id in (
with test_cte (id,name) as (
select id, name
from test
)
select id
from test_cte
where name = 'john'
)
Is there a way to do this?
Do you just mean this:
;with test_cte(id,name) as
(
select id,name from dbo.test
)
delete test_cte where name='john';
Do you want to delete rows and show the rows you deleted?
;with test_cte(id,name) as
(
select id,name from dbo.test
)
delete test_cte
output deleted.id, deleted.name
where name='john';
Example db<>fiddle
To take your explicit example:
delete from test
where id in (
with test_cte (id,name) as (
select id, name
from test
)
select id
from test_cte
where name = 'john'
)
You're getting a syntax error because, well, there's an error in your syntax. CTE must be defined up front, not in any random or arbitrary point in your query.
;with test_cte (id,name) as (
select id, name
from test
)
delete from test
where id in (
select id
from test_cte
where name = 'john'
)
But this still seems awfully over-complicated compared to the simpler examples I've shown.
I have a table that has 3 columns.
create table myTable
(
ID int Primary key,
Detail_ID int references myTable(ID) null, -- reference to self
Master_Value varchar(50) -- references to master table
)
this table has the follow records:
insert into myTable select 100,null,'aaaa'
insert into myTable select 101,100,'aaaa'
insert into myTable select 102,101,'aaaa'
insert into myTable select 103,102,'aaaa' ---> last record
insert into myTable select 200,null,'bbbb'
insert into myTable select 201,200,'bbbb'
insert into myTable select 202,201,'bbbb' ---> last record
the records is saved In the form of relational with ID and Detail_ID columns.
I need to select the last record each Master_Value column. follow output:
lastRecordID Master_Value Path
202 bbbb 200=>201=>202
103 aaaa 100=>101=>102=>103
tips:
The records are not listed in order in the table.
I can not use the max(ID) keyword. beacuse data is not sorted.(may
be the id column updated manually.)
attempts:
I was able to Prepare follow query and is working well:
with Q as
(
select ID ,Detail_ID, Master_Value , 1 RowOrder, CAST(id as varchar(max)) [Path] from myTable where Detail_ID is null
union all
select R.id,R.Detail_ID , r.Master_Value , (q.RowOrder + 1) RowOrder , (q.[Path]+'=>'+CAST(r.id as varchar(max))) [Path] from myTable R inner join Q ON Q.ID=R.Detail_ID --where r.Dom_ID_RowType=1010
)
select * into #q from Q
select Master_Value, MAX(RowOrder) lastRecord into #temp from #Q group by Master_Value
select
q.ID lastRecordID,
q.Master_Value,
q.[Path]
from #temp t
join #q q on q.RowOrder = t.lastRecord
where
q.Master_Value = t.Master_Value
but I need to simple way (one select) and optimal method.
Can anyone help me?
One method uses a correlated subquery to get the last value (which is how I interpreted your question):
select t.*
from mytable t
where not exists (select 1
from mytable t2
where t2.master_value = t.master_value and
t2.id = t.detail_id
);
This returns rows that are not referred to by another row.
For the path, you need a recursive CTE:
with cte as (
select master_value, id as first_id, id as child_id, convert(varchar(max), id) as path, 1 as lev
from mytable t
where detail_id is null
union all
select cte.master_value, cte.first_id, t.id, concat(path, '->', t.id), lev + 1
from cte join
mytable t
on t.detail_id = cte.child_id and t.master_value = cte.master_value
)
select cte.*
from (select cte.*, max(lev) over (partition by master_value) as max_lev
from cte
) cte
where max_lev = lev
Here is a db<>fiddle.
I have this table:
Profile_id Phase_id order
30087853 30021628 525
30087853 30021635 523
30087853 30021673 122
30087853 30021703 521
from the above I would like to get profile_id along with this phase_id, which has lowest order_num, so the outcome will be like:
Profile_id Phase_id order
30087853 30021673 122
You didn't specify your DBMS so this is standard SQL:
select profile_id, phase_id, "order"
from (
select profile_id, phase_id, "order",
row_number() over (partition by profile_id order by "order") as rn
from the_table
) t
where rn = 1;
Online example: http://rextester.com/MAUV44954
Without a sub-query or self-join you can use also this one:
SELECT Profile_id, MIN("order") as "order",
MIN(Phase_id) KEEP (DENSE_RANK FIRST ORDER BY "order") AS Phase_id
FROM your_table
GROUP BY Profile_id;
CREATE TABLE #table(Profile_id INT, Phase_id INT, _order INT)
INSERT INTO #table(Profile_id , Phase_id , _order )
SELECT 30087853,30021628,525 UNION ALL
SELECT 30087853,30021635,523 UNION ALL
SELECT 30087853,30021673,122 UNION ALL
SELECT 30087853,30021703,521
SELECT *
FROM #table T1
JOIN
(
SELECT Profile_id ProfileId, MIN(_order) [order]
FROM #table
GROUP BY Profile_id
) A ON T1.Profile_id = ProfileId AND T1._order = [order]
There is one table T ( id integer, primary key ( id).
I want a parameterized query that, given id i:
will return next consecutive id,
if i = biggest id in T, query should return the smallest id in T (cyclical)
You can select the smallest id over the value #i (if any), and the smallest id, then get the largest:
select max(id)
from (
select top 1 id
from T
where id > #i
order by id
union all
select top 1 id
from T
order by id
) x
Or perhaps:
select max(id)
from (
select min(id) as id
from T
where id > #i
union all
select min(id)
from T
) x
This appears to be what you're looking for:
CREATE PROCEDURE dbo.ProcName
(
#ID INTEGER
)
AS
SELECT TOP 1 id
FROM table
WHERE id > #ID
ORDER BY id