SQL server: difference between DELETE <Table> and DELETE from <Table> - sql

SQL server:
Difference between :
Delete tblxyz where id=6
and :
Delete from tblxyz where id=6
Is their any difference between above queries ?

There is no difference if you see the execution plan both generates delete scripts as below
DELETE [testtable] WHERE [numbers]=#1

There is no direct difference between the two statements
(except that I find the "DELETE FROM" easier to read and understand)
note that ANSI does require the "FROM" keyword as stated by jarlh
see also
https://msdn.microsoft.com/en-us/library/ms189835.aspx

There is no difference in your delete.
However, the FROM clause is a fully functional from clause, so you can use it with JOIN. For instance:
delete t
from t join
(select min(id) as minid
from t
group by grp
) tt
on t.id = tt.minid;
This would delete the record with the minimum id for each grp value. The alias after the delete is needed to specify which table to delete from (although in this case, deleting from an aggregation result is not allowed).
Note: This query is for illustrative purposes. There is nothing wrong with the query, but it is not how I would actually write such a query in SQL Server.

According to the MSDN the word "from" is optional. The default is not to use:
FROM
and the target table_or_view_name, or rowset_function_limited.An optional keyword that can be used between the DELETE keyword
However in MS Access (or may be some other databases) you may delete a row using delete * command, so you have to use from:
delete * from phoneBook where....

The from Clause is optional..Below is stripped down version of Syntax..
DELETE
[ TOP ( expression ) [ PERCENT ] ]
[ FROM ]
{ { table_alias
FROM
An optional keyword that can be used between the DELETE keyword and the target table_or_view_name, or rowset_function_limited.

Related

Return deleted rows in sqlite

It's not efficient to do two queries like SELECT * FROM TABLE WHERE clause and then DELETE * FROM TABLE WHERE clause.
So I want to make DELETE query and return deleted rows (one query).
I tried to do:
DELETE OUTPUT DELETED.*
FROM table
WHERE clause
But I have an error:
SQLite exception: near "OUTPUT": syntax error
How to make it correctly or maybe there is another alternative way to return deleted rows?
The DELETE statement has no OUTPUT clause.
After doing the SELECT, all the important data is in the cache, so the DELETE will run quickly.
And because SELECT plus DELETE is the only way, it is the most efficient way.
Since version 3.35, SQLite has the RETURNING clause.
You can return the records deleted with the returning clause
delete from myTable returning *
You can use the changes() call right after your DELETE query: https://www.sqlite.org/c3ref/changes.html
Implementation will vary depending on the language you're using. For example in PHP you could write:
$sqlite = new SQLite3('database.sqlite');
$statement = $sqlite->prepare('DELETE FROM mytable WHERE myclause');
$statement->execute();
echo $sqlite->changes();

Why does DELETE FROM ... FROM ... not error out?

This bit within a stored proc is apparently valid sql:
DELETE TOP (#MaxRecords)
FROM Table
FROM Table B
INNER JOIN Table2 R ON B.fk = R.pk
WHERE R.Value < #DecVariable;
How can two FROM statements be put together and yet still be valid?
First of all TOP in delete syntax indicates that it is SQL Server.
It is perfect valid query, see DELETE:
FROM
An optional keyword that can be used between the DELETE keyword and the target table_or_view_name, or rowset_function_limited.
FROM table_source
Specifies an additional FROM clause. This Transact-SQL extension to DELETE allows specifying data from and deleting the
corresponding rows from the table in the first FROM clause.
This extension, specifying a join, can be used instead of a subquery in the WHERE clause to identify rows to be removed.
DELETE:
Object:

Sub-Queries in Sybase SQL

We have an application which indexes data using user-written SQL statements. We place those statements within parenthesis so we can limit that query to a certain criteria. For example:
select * from (select F_Name from table_1)q where ID > 25
Though we have discovered that this format does not function using a Sybase database. Reporting a syntax error around the parenthesis. I've tried playing around on a test instance but haven't been able to find a way to achieve this result. I'm not directly involved in the development and my SQL knowledge is limited. I'm assuming the 'q' is to give the subresult an alias for the application to use.
Does Sybase have a specific syntax? If so, how could this query be adapted for it?
Thanks in advance.
Sybase ASE is case sensitive w.r.t. all identifiers and the query shall work:
as per #HannoBinder query :
select id from ... is not the same as select ID from... so make sure of the case.
Also make sure that the column ID is returned by the Q query in order to be used in where clause .
If the table and column names are in Upper case the following query shall work:
select * from (select F_NAME, ID from TABLE_1) Q where ID > 25

Update from aggregate in same table if aggregate value wrong - SQL Server/Oracle/Firebird

I have a table with grouped tasks:
tt_plan_task_id is the id
records with tt_plantype=1 represent 'groups'
tasks in/under a group have a tt_group_id pointing to the tt_plan_task_id
there are tasks that don't belong to a group (tt_group_id is null)
groups nest multiple levels
I need to fix (update) the tt_fromdate field values for the group records if they do not match the min(tt_fromdate) from the underlying tasks (they always have a value).
To fix them all I could do
update tt_plan_task g
set tt_fromdate=
(select min(t.tt_fromdate) from tt_plan_task t
where (t.tt_group_id=g.tt_plan_task_id))
where (g.tt_plantype=1)
This statement avoids the UPDATE FROM syntax that I see in many (SQL server) answers - Firebird does not support that.
There are 2 complications
I want to do the update only if g.tt_fromdate <> min(t.tt_fromdate), so I would have to add a reference to min(tt_fromdate) to the outer where.
I tried using an alias for the aggregate and referencing that but that got me nowhere (syntax errors)
SQL Server does not like the table alias in the update, but solutions like these use the UPDATE FROM syntax again ;-( How do I work around that then?
How do I tie 1. and 2. into my update statement so that it works?
As noted in the title, this needs to execute in SQL Server, Oracle, and Firebird
Note: Since groups can contain groups, the update should ideally be executed 'from the bottom up', i.e. deepest groups first.
But since this is just a rough correction for a corrupt database, doing one 'lineair' pass over all groups is good enough.
To get around SQL Server's non-standard way for update table aliases, simply don't use any.
As to using the aggregate result in both the SET clause and the WHERE clause, I suppose the only way all DBMS work with, is to write the aggregation query twice.
update tt_plan_task
set tt_fromdate =
(
select min(t.tt_fromdate)
from tt_plan_task t
where t.tt_group_id = tt_plan_task.tt_plan_task_id
)
where (tt_plantype=1)
and
(
tt_fromdate <>
(
select min(t.tt_fromdate)
from tt_plan_task t
where t.tt_group_id = tt_plan_task.tt_plan_task_id
)
);

Using CTE with while loop in SQL server 2005

I want to use CTE with while loop. Is it possible
my code:
; with myCTE(a,b)
(
select .,. from abc
)
while exist (select * from mycet) -- causing issue
Please suggest some solution.
Regards,
Anuprita
No, the documentation states:
A CTE must be followed by a single SELECT, INSERT, UPDATE, or DELETE
statement that references some or all the CTE columns.
But you should use a set based approach instead of loops anyway. Apart from that, it is not clear what your query should return.