How to get DELETE FROM [QUERY] to work? - sql

Hi I'm kinda new to mssql, I'm used to Oracle. I'm trying to delete a specific row from a subquery but mssql doens't really like subqueries.
Here is the query:
DELETE FROM (SELECT *, ROW_NUMBER() OVER (PARTITION BY column1 ORDER BY column1) row FROM randomtable) a
WHERE a.row = 1
Is there a way to get this to work?
In Oracle I could've get everything in a query because I can use rownum = 1.

You were nearly there
DELETE a
FROM (SELECT *,
ROW_NUMBER() OVER (PARTITION BY column1 ORDER BY column1) row
FROM randomtable) a
WHERE a.row = 1
Though I prefer the CTE syntax
WITH a
AS (SELECT *,
ROW_NUMBER() OVER (PARTITION BY column1 ORDER BY column1) row
FROM randomtable)
DELETE FROM a
WHERE a.row = 1

You didn't specify the table alias in what you wanted to delete from.
DELETE a FROM (SELECT *, ROW_NUMBER() OVER (PARTITION BY column1 ORDER BY column1) row FROM randomtable) a
WHERE a.row = 1

Write the alias DELETE a FROM ...

Related

Creating column and filtering it in one select statement

Wondering if it is possible to creating a new column and filter on that column. The following is an example:
SELECT row_number() over (partition by ID order by date asc) row# FROM table1 where row# = 1
Thanks!
Some databases support a QUALIFY clause which you might be able to use:
SELECT *
FROM table1
QUALIFY ROW_NUMBER() OVER (PARTITION BY ID ORDER BY date) = 1;
On SQL Server, you may use a TOP 1 WITH TIES trick:
SELECT TOP 1 WITH TIES *
FROM table1
ORDER BY ROW_NUMBER() OVER (PARTITION BY ID ORDER BY date);
More generally, you would have to use a subquery:
WITH cte AS (
SELECT t.*, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY date) rn
FROM table1 t
)
SELECT *
FROM cte
WHERE rn = 1;
The WHERE clause is evaluated before the SELECT so your column has to exist before you can use a WHERE clause. You could achieve this by making a subquery of the original query.
SELECT *
FROM
(
SELECT row_number() over (partition by ID order by date asc) row#
FROM table1
) a
WHERE a.row# = 1

Cannot recognize input near 'DELETE' 'FROM' 'CTE' in statement

I want to drop duplicates in mytable if there are identical value in col1.
WITH CTE AS
(
SELECT
*, ROW_NUMBER() OVER (PARTITION BY col1 ORDER BY col1) AS RN
FROM
mytable
)
DELETE FROM CTE
WHERE RN <> 1
I got error:
Cannot recognize input near 'DELETE' 'FROM' 'CTE' in statement
I don't think Hive supports that syntax for DELETE. Try this:
DELETE FROM mytable t
WHERE t.id > (SELECT MIN(t2.id) -- some sort of unique id
FROM t t2
WHERE t2.id = t.id
);
If you have complete duplicates, then the above won't work. In the most recent versions of Hive you can use MERGE. In older versions:
create table temp_t as
select distinct t.*
from t;
truncate table t;
insert into t
select * from temp_t;
Of course, backup the table before trying this!
Alternative way: assuming you have UNIQUE ID Column.
Delete from MyTable where ID in
(SELECT ID FROM (SELECT *, ROW_NUMBER() OVER (PARTITION BY col1 ORDER BY col1) AS RN
FROM mytable) a where RN <> 1)

Update table using result of another query

I have the following query that works fine
SELECT RecordID, ROW_NUMBER() OVER (ORDER BY (Value1) DESC) AS Rank
FROM Table1
Also, I have another table(table2) that contains (among others) the fields RecordID and Rank. I would like to update RecordID and Rank in table2 based on result of query above. Is that possible?
Yes, you can have multiple tables in an update in Postgres:
update table2
set rank = t1.rank
from (SELECT RecordID, ROW_NUMBER() OVER (ORDER BY (Value1) DESC) AS Rank
FROM Table1
) t1
where table2.RecordId = t1.RecordId;
What worked for me (in mysql) was :
update table2, (SELECT RecordID, ROW_NUMBER() OVER (ORDER BY (Value1) DESC) AS Rank
FROM Table1) tempTable
set table2.Rank = tempTable.Rank
where table2.RecordId = tempTable.RecordId;

Multiple columns in OVER ORDER BY

Is there a way to specify multiple columns in the OVER ORDER BY clause?
SELECT ROW_NUMBER() OVER(ORDER BY (A.Col1)) AS ID FROM MyTable A
The above works fine, but trying to add a second column does not work.
SELECT ROW_NUMBER() OVER(ORDER BY (A.Col1, A.Col2)) AS ID FROM MyTable A
Incorrect syntax near ','.
The problem is the extra parentheses around the column name. These should all work:
-- The standard way
SELECT ROW_NUMBER() OVER(ORDER BY A.Col1) AS ID FROM MyTable A
SELECT ROW_NUMBER() OVER(ORDER BY A.Col1, A.Col2) AS ID FROM MyTable A
-- Works, but unnecessary
SELECT ROW_NUMBER() OVER(ORDER BY (A.Col1), (A.Col2)) AS ID FROM MyTable A
Also, when you ask an SQL question, you should always specify which database you are querying against.
No brackets.
SELECT ROW_NUMBER() OVER(ORDER BY A.Col1, A.Col2) AS ID FROM MyTable A

Selecting a given row in a table

here is a simple problem. I have a table of 500 rows and what to be able to select a given row number n. This is what I am doing:
select *
from table
where table.arg1 ='A'
and time_stamp=to_date('1/8/2010','MM/DD/YYYY')
and rownum = n
But it would only work for the row 1, for the rest it doesn't return anything. Any idea?
The reason why where rownum = 3 returns an empty rowset is that the condition is not true for the first row. For the second row, there is still no first row in the resultset, and rownum is still 1. So the condition fails again. See this page for a more detailed explanation.
You can use row_number() in a subquery:
select *
from (
select row_number() over (order by col1) as rn, yt.*
from YourTable yt
) sub
where rn = 3
Or even simpler, but perhaps more confusing, using rownum itself:
select *
from (
select rownum as rn, yt.*
from YourTable yt
) sub
where rn = 3