SQL update query according to row sequence number - sql

I have a table and I want to update this table using SQL query statement.
How can i write a statement to update the 3rd row for example?
What I mean is that I want to make update to a certain row according to its appearance sequence in the table.

3rd row
When ordered by what? SQL databases make no guarantee to the order of records in any given query unless explicitly given an ORDER BY clause.
Identify the row you want to update using a WHERE clause. For example:
UPDATE SomeTable SET SomeColumn = 'Some Value' WHERE AnotherColumn = 'Another Value'
You can chain together lots of boolean logic into that WHERE clause to create more complex ways of identifying the record(s) you want to update. But the point is that you have to identify the record. "The 3rd row" doesn't mean anything to SQL.
Once you do have that ORDER BY clause, you can perhaps do something a little more complex. For example, sort the records in a sub-query and use an identifier from that query. So you might get "the 3rd row" like this:
SELECT ID FROM SomeTable ORDER BY ID OFFSET 2 LIMIT 1
Then use that in the UPDATE:
UPDATE SomeTable SET SomeColumn = 'Some Value'
WHERE ID IN (SELECT ID FROM SomeTable ORDER BY ID OFFSET 2 LIMIT 1)
(assuming MySQL, since you didn't specify, but other RDBMS engines have similar capabilities)

I don't know which DBMS you're using. If you're using Oracle DB there are pseudocolumns ROWID and ROWNUM you could use for this purpose.

Related

Does Snowflake preserve retrieval order?

Posting two questions:
1.
Let's say there is a query:
SELECT C1, C2, C3 from TABLE;
When this query is fired for the first time,it retrieves all the values in a certain order.
Next time, when the same query is fired, will the previous order be retained?
There are 2 tables, TABLE1 and TABLE2, both of them have identical data.
Will (SELECT * from TABLE1) and (SELECT * from TABLE1) retrieve the same order of rows?
SQL tables represent unordered sets. Period. There is no ordering in a result set unless you explicitly include an ORDER BY.
It is that simple. If you want data in a particular order, then you need to use ORDER BY. That is how relational databases work.
The same query can return results in different orders each time the query is executed. There are no guarantees about the order -- unless the query has an ORDER BY for the outermost SELECT.
No, unless you are fetching data from result cache!
No, unless they are very small tables and your query runs with low parallelism.
Sorry for extra answer, but I see Tim claims that the query will return same result as long as the underlying table(s) is not modified, and the query has same execution plan.
Snowflake executes the queries in parallel, therefore the order of data is not predictable unless ORDER BY is used.
Let's create a table (big enough to be processed in parallel), and run a simple test case:
-- running on medium warehouse
create or replace table my_test_table ( id number, name varchar ) as
select seq4(), 'gokhan' || seq4() from table(generator(rowcount=>1000000000));
alter session set USE_CACHED_RESULT = false;
select * from my_test_table limit 10;
You will see that it will return different rows every time you run.
To answer both questions short: No.
If your query has no ORDER BY-clause, the SELECT statement always returns an unordered set. This means: Even if you query the same table twice and the data didnt change, SELECT without ORDER BY can retrieve different row-orders.
https://docs.snowflake.com/en/sql-reference/sql/select.html

Table Value parameter cursor order

I'm passing a single string column table parameter (no other option, must be one column). I've read that there's no guarantee of order on a TVP, but all the articles I've read are referring to a select statement. If I run a cursor on a TVP, will it always read from first record to last?
Table-valued parameter is a table, a temporary table.
Any table, including temporary tables in SQL Server is an unordered set of rows.
When you write
SELECT Column1 FROM Table1
the server can return rows in any order it chooses. It will return all rows of a table, of course, you just can't predict in which order.
If you need some specific order, then you have to specify ORDER BY clause, like this:
SELECT Column1 FROM Table1 ORDER BY Column2
All this applies to TVP and cursors.
If you define a cursor without ORDER BY, it will read through all rows, but in some unspecified order, which may vary with each run. If you need the cursor to process rows of TVP in some specific order, then specify the ORDER BY clause in the SELECT statement of the cursor definition.
In other words, the cursor will always read from the "first" record to the "last". If it is important to the logic of the cursor to have defined what is "first" and what is "last" you need to add ORDER BY clause.

behavior of select when MAX() is present

Get other columns that correspond with MAX value of one column?
I know that when SELECT, sql usually gives all rows from the table(without WHERE condition).
but why this time sql gives data of only the first row for other columns(video_category, url, ...)?
does MAX() changes the behavior of SELECT?
if so, why the rest of columns are not derived from row of MAX(id)?
If you want all columns from the record having the max id, then you will have to use a subquery:
SELECT *
FROM yourTable
WHERE id = (SELECT MAX(id) FROM yourTable);
Your current output is only one record because when say take the max over the entire table, you are no longer speaking of individual records. I am guessing that you are using MySQL, in which case the values you see for the other columns were chosen by the database. But there is no guarantee about which record was chosen.
Some versions of SQL (e.g. MySQL, SQL Server), support LIMIT/TOP functionality which might simplify things. For example, on SQL Server we can just write:
SELECT TOP 1 *
FROM yourTable
ORDER BY id DESC;

SELECT COUNT(*) ;

I have a database, database1, with two tables (Table 1, Table2) in it.
There are 3 rows in Table1 and 2 rows in Table2. Now if I execute the following SQL query SELECT COUNT(*); on database1, then the output is "1".
Does anyone has the idea, what this "1" signifies?
The definition of the two tables is as below.
CREATE TABLE Table1
(
ID INT PRIMARY KEY,
NAME NVARCHAR(20)
)
CREATE TABLE Table2
(
ID INT PRIMARY KEY,
NAME NVARCHAR(20)
)
Normally all selects are of the form SELECT [columns, scalar computations on columns, grouped computations on columns, or scalar computations] FROM [table or joins of tables, etc]
Because this allows plain scalar computations we can do something like SELECT 1 + 1 FROM SomeTable and it will return a recordset with the value 2 for every row in the table SomeTable.
Now, if we didn't care about any table, but just wanted to do our scalar computed we might want to do something like SELECT 1 + 1. This isn't allowed by the standard, but it is useful and most databases allow it (Oracle doesn't unless it's changed recently, at least it used to not).
Hence such bare SELECTs are treated as if they had a from clause which specified a table with one row and no column (impossible of course, but it does the trick). Hence SELECT 1 + 1 becomes SELECT 1 + 1 FROM ImaginaryTableWithOneRow which returns a single row with a single column with the value 2.
Mostly we don't think about this, we just get used to the fact that bare SELECTs give results and don't even think about the fact that there must be some one-row thing selected to return one row.
In doing SELECT COUNT(*) you did the equivalent of SELECT COUNT(*) FROM ImaginaryTableWithOneRow which of course returns 1.
Along similar lines the following also returns a result.
SELECT 'test'
WHERE EXISTS (SELECT *)
The explanation for that behavior (from this Connect item) also applies to your question.
In ANSI SQL, a SELECT statement without FROM clause is not permitted -
you need to specify a table source. So the statement "SELECT 'test'
WHERE EXISTS(SELECT *)" should give syntax error. This is the correct
behavior.
With respect to the SQL Server implementation, the FROM
clause is optional and it has always worked this way. So you can do
"SELECT 1" or "SELECT #v" and so on without requiring a table. In
other database systems, there is a dummy table called "DUAL" with one
row that is used to do such SELECT statements like "SELECT 1 FROM
dual;" or "SELECT #v FROM dual;". Now, coming to the EXISTS clause -
the project list doesn't matter in terms of the syntax or result of
the query and SELECT * is valid in a sub-query. Couple this with the
fact that we allow SELECT without FROM, you get the behavior that you
see. We could fix it but there is not much value in doing it and it
might break existing application code.
It's because you have executed select count(*) without specifying a table.
The count function returns the number of rows in the specified dataset. If you don't specify a table to select from, a single select will only ever return a single row - therefore count(*) will return 1. (In some versions of SQL, such as Oracle, you have to specify a table or similar database object; Oracle includes a dummy table (called DUAL) which can be selected from when no specific table is required.)
you wouldn't normally execute a select count(*) without specifying a table to query against. Your database server is probably giving you a count of "1" based on default system table it is querying.
Try using
select count(*) from Table1
Without a table name it makes no sense.
without table name it always return 1 whether it any database....
Since this is tagged SQL server, the MSDN states.
COUNT always returns an int data type value.
Also,
COUNT(*) returns the number of items in a group. This includes NULL
values and duplicates.
Thus, since you didn't provide a table to do a COUNT from, the default (assumption) is that it returns a 1.
COUNT function returns the number of rows as result. If you don't specify any table, it returns 1 by default. ie., COUNT(*), COUNT(1), COUNT(2), ... will return 1 always.
Select *
without a from clause is "Select ALL from the Universe" since you have filtered out nothing.
In your case, you are asking "How many universe?"
This is exactly how I would teach it. I would write on the board on the first day,
Select * and ask what it means. Answer: Give me the world.
And from there I would teach how to filter the universe down to something meaningful.
I must admit, I never thought of Select Count(*), which would make it more interesting but still brings back a true answer. We have only one world.
Without consulting Steven Hawking, SQL will have to contend with only 1.
The results of the query is correct.

Getting additional info on the result of a SQL max query

Say I want to do this with SQL (Sybase): Find all fields of the record with the latest timestamp.
One way to write that is like this:
select * from data where timestamp = (select max(timestamp) from data)
This is a bit silly because it causes two queries - first to find the max timestamp, and then to find all the data for that timestamp (assume it's unique, and yes - i do have an index on timestamp). More so it just seems unnecessary because max() has already found the row that I am interested in so looking for it again is wasteful.
Is there a way to directly access fields of the row that max() returns?
Edit: All answers I see are basically clever hacks - I was looking for a syntactic way of doing something like max(field1).field2 to access field2 of the row with max field1
SELECT TOP 1 * from data ORDER BY timestamp DESC
No, using an aggregate means that you are automatically grouping, so there isn't a single row to get data from even if the group happens to contain a single row.
You can order by the field and get the first row:
set rowcount 1
select * from data order by timestamp desc
(Note that you shouldn't use select *, but rather specify the fields that you want from the query. That makes the query less sensetive to changes in the database layout.)
Can you try this
SELECT TOP 1 *
FROm data
ORDER BY timestamp DESC
You're making assumptions about how Sybase optimizes queries. For all you know, it may do precisely what you want it to do - it may notice both queries are from "data" and that the condition is "where =", and may optimize as you suggest.
I know in the case of SQL Server, it's possible to configure indexes to include fields from the indexed row. Doing a select through such an index leaves those fields available.
This is SQL server, but you'll get the idea.
SELECT TOP(1) * FROM data
ORDER BY timestamp DESC;