I am studying the query in the answer of the post IN operator in SQL Statement Does not work?, as below:
DELETE t FROM (SELECT t.*, ROW_NUMBER(*) OVER (PARTITION BY P ORDER BY ABS((P & 0xFFFFFFFF) * 256 - F) as seqnum FROM MyTable t ) t WHERE seqnum > 1; After many researchs, I finally figure out most of the issues, and revised the query as below:
DELETE t2 FROM (SELECT t.*, ROW_NUMBER() OVER (PARTITION BY P ORDER BY ABS((P & 0xFFFFFFFF) * 256 - F)) as seqnum FROM MyTable t ) t2 WHERE seqnum > 1; The changes are:
- Add ")" after "F)", so that "OVER (PARTITION BY P ORDER BY ABS((P & 0xFFFFFFFF) * 256 - F))" follow the syntax at https://learn.microsoft.com/en-us/sql/t-sql/queries/select-over-clause-transact-sql?view=sql-server-ver15
- Change ROW_NUMBER(*) to ROW_NUMBER() since the document above use ROW_NUBMER().
- Change the t in the outer query to t2. The subquery in FROM clause must have an alias, so there must be an alias after the subquery. See (T-SQL) Why does this subquery need an alias? . Moreover, actual the alias in the outer query can be same as the one in the subquery, see https://dba.stackexchange.com/questions/16516/subqueries-aliases-same-as-main-queries-aliases, but they are refer to different objects. So I change the alias in the outer query from "t" to "t2"
It is a bit difficult for a novice to understand many knowledges in a complex query. Whatmore, I still have two things that cannot understand very well.
- Why I must write "Delete t2 FROM" instead of "Delete FROM"? I only find this link Difference between DELETE and DELETE FROM in SQL? , but it is used for JOIN table, not for subquery.
- From the link at https://dba.stackexchange.com/questions/120233/sql-server-delete-from-subquery-derived-table, I know the subquery is a derived table. Then the DELETE from t2 is just delete records from a dervied table(it is virtual), why it can also perform the same deletion operation on the underlying real table MyTable?
Thanks
DELETE. You can writeDELETE FROM t2 FROM <some subquery>. You can write the keywordFROMtwice. The firstFROMis optional. It much more readable to wrap subquery in CTE, as @Lukasz showed in his answer.