Select statement in SQLite recognizing row number - sql

I want to write SQLite statement something like this:
SELECT * FROM Table WHERE RowNumber BETWEEN 1 AND 10;
but i don't have such column RowNumber. I have primary key in my table. But is there row number by default that i could use ?
Also i am searching info about writing more complicated SQLite statement. So if you have some links in bookmarks please share.
Thanks.

You want to use LIMIT and OFFSET
SELECT * FROM Table LIMIT 10 OFFSET 0
Which can also be expressed with the following shorthand syntax
SELECT * FROM Table LIMIT X,Y
Where X represents the offset, which is exclusive, and Y represents the quantity, so for example
SELECT * FROM Table LIMIT 50,50
Would return rows 51-100

The automatically-created rowid for a table can be accessed by a few different names. From the SQLite documentation:
Every row of every SQLite table has a 64-bit signed integer key that uniquely identifies the row within its table. This integer is usually called the "rowid". The rowid value can be accessed using one of the special case-independent names "rowid", "oid", or "_rowid_" in place of a column name.

SELECT * FROM Table WHERE ROWID BETWEEN 1 AND 10;

Related

Create virtual table with rowid only of another table

Suppose I have a table in sqlite as follows:
`name` `age`
"bob" 20 (rowid=1)
"tom" 30 (rowid=2)
"alice" 19 (rowid=3)
And I want to store the result of the following table using minimal storage space:
SELECT * FROM mytable WHERE name < 'm' ORDER BY age
How can I store a virtual table from this resultset that will just give me the ordered resultset. In other words, storing the rowid in an ordered way (in the above it would be 3,1) without saving all the data into a separate table.
For example, if I stored this information with just the rowid in a sorted order:
CREATE TABLE vtable AS
SELECT rowid from mytable WHERE name < 'm' ORDER BY age;
Then I believe every time I would need to query the vtable I would have to join it back to the original table using the rowid. Is there a way to do this so that the vtable "knows" the content that it has based on the external table (I believe this is referred to as external-content when creating an fts index -- https://sqlite.org/fts5.html#external_content_tables).
I believe this is referred to as external-content when creating an
fts.
No a virtual table is CREATED using CREATE VIRTUAL TABLE ...... USING module_name (module_parameters)
Virtual tables are tables that can call a module, thus the USING module_name(module_parameters) is mandatory.
For FTS (Full Text Serach) you would have to read the documentation but it could be something like
CREATE VIRTUAL TABLE IF NOT EXISTS bible_fts USING FTS3(book, chapter INTEGER, verse INTEGER, content TEXT)
You very likely don't need/want a VIRTUAL table.
CREATE TABLE vtable AS SELECT rowid from mytable WHERE name < 'm' ORDER BY age;
Would create a normal table IF it didn't already exist that would persist. And if you wanted to use it then it would probably only be of use by joining it with mytable. Effectively it would allow a snapshot, but at a cost, of at least 4k for every snapshot.
I'd suggest a single table for all snapshots that has two columns a snapshot identifier and the rowid of the snapshot. This would probably be far less space consuming.
Basic Example
Consider :-
CREATE TABLE IF NOT EXISTS mytable (
id INTEGER PRIMARY KEY, /* NOTE not using an alias of the rowid may present issues as the id's can change */
name TEXT,
age INTEGER
);
CREATE TABLE IF NOT EXISTS snapshot (id TEXT DEFAULT CURRENT_TIMESTAMP, mytable_map);
INSERT INTO mytable (name,age) VALUES('Mary',21),('George',22);
INSERT INTO snapshot (mytable_map) SELECT id FROM mytable;
SELECT snapshot.id,name,age FROM snapshot JOIN mytable ON mytable.id = snapshot.mytable_map;
And the above is run 3 times with a reasonable interval (seconds so as to distinguish the snapshot id (the timestamp)).
Then you would get 3 snapshots (each with a number of rows but the same value in the id column for each snapshot), the first with 2 rows, the 2nd with 4 and the last with 6 (as each run 2 rows are being added to mytable) :-

update rows one by one with max value + 1 in SQL

here is my situation,
I have 2 tables,
1st table has all records, and it has IDs
2nd table has new records and it doesnt have ID, yet.
I want to generate ID for 2nd table with max(id) + 1 from 1st table.
when i do this, it makes all rows same id number, but i want to make it unique increment number.
e.g
select max(id) from table1 then it gives '997040'
I want to make second table rows like;
id
997041
997042
997043
997044
i think i need to use cursor or whileloop, or both, but i could not create the actual query.
sorry about bad explanation, i am so confused now
Use ROWNUM to generate incrementing row numbers. E.g.:
SELECT someConstant + ROWNUM FROM source.
CREATE TABLE table_name
(
ID int IDENTITY(997041,1) PRIMARY KEY
)
I hope this sql query would work!!
Or refer http://www.w3schools.com/sql/sql_autoincrement.asp

Select last value in a specific column? (PostgreSQL)

Running into some issues when trying to retrieve the last value in a specific column, from a table and assign it into a variable.
Looking for the last int in a column "id" that is a primary key basically.
So I have a variable like "lastValue" in a select statement like :
select last(id) into lastValue from test_table
Not sure on an exact, or best way to accomplish this.
(on mobile, please forgive formatting)
A typical way to solve this is with order by and limit:
select id
from test_table
order by id desc
limit 1;
Of course, in this case, you could simply use:
select max(id)
from test_table;
But the first method allows you to choose whichever variables you want from the row with the maximum value.

How to return record count in PostgreSQL

I have a query with a limit and an offset. For example:
select * from tbl
limit 10 offset 100;
How to keep track of the count of the records, without running a second query like:
select count(*) from tbl;
I think this answers my question, but I need it for PostgreSQL. Any ideas?
I have found a solution and I want to share it. What I do is - I create a temp table from my real table with the filters applied, then I select from the temp table with a limit and offset (no limitations, so the performance is good), then select count(*) from the temp table (again no filters), then the other stuff I need and last - I drop the temp table.
select * into tmp_tbl from tbl where [limitations];
select * from tmp_tbl offset 10 limit 10;
select count(*) from tmp_tbl;
select other_stuff from tmp_tbl;
drop table tmp_tbl;
I haven't tried this, but from the section titled Obtaining the Result Status in the documentation you can use the GET DIAGNOSTICS command to determine the effect of a command.
GET DIAGNOSTICS number_of_rows = ROW_COUNT;
From the documentation:
This command allows retrieval of system status indicators. Each item
is a key word identifying a state value to be assigned to the
specified variable (which should be of the right data type to receive
it). The currently available status items are ROW_COUNT, the number of
rows processed by the last SQL command sent down to the SQL engine,
and RESULT_OID, the OID of the last row inserted by the most recent
SQL command. Note that RESULT_OID is only useful after an INSERT
command into a table containing OIDs.
Depends if you need it from the psql CLI or if you're accessing the database from something like an HTTP server. I am using postgres from my Node server with node-postgres. The result set is returned as an array called 'rows' on the result object so I can just do
console.log(results.rows.length)
To get the row count.

Equivalent of Oracle's RowID in SQL Server

What's the equivalent of Oracle's RowID in SQL Server?
From the Oracle docs
ROWID Pseudocolumn
For each row in the database, the ROWID pseudocolumn returns the
address of the row. Oracle Database rowid values contain information
necessary to locate a row:
The data object number of the object
The data block in the datafile in which the row resides
The position of the row in the data block (first row is 0)
The datafile in which the row resides (first file is 1). The file
number is relative to the tablespace.
The closest equivalent to this in SQL Server is the rid which has three components File:Page:Slot.
In SQL Server 2008 it is possible to use the undocumented and unsupported %%physloc%% virtual column to see this. This returns a binary(8) value with the Page ID in the first four bytes, then 2 bytes for File ID, followed by 2 bytes for the slot location on the page.
The scalar function sys.fn_PhysLocFormatter or the sys.fn_PhysLocCracker TVF can be used to convert this into a more readable form
CREATE TABLE T(X INT);
INSERT INTO T VALUES(1),(2)
SELECT %%physloc%% AS [%%physloc%%],
sys.fn_PhysLocFormatter(%%physloc%%) AS [File:Page:Slot]
FROM T
Example Output
+--------------------+----------------+
| %%physloc%% | File:Page:Slot |
+--------------------+----------------+
| 0x2926020001000000 | (1:140841:0) |
| 0x2926020001000100 | (1:140841:1) |
+--------------------+----------------+
Note that this is not leveraged by the query processor. Whilst it is possible to use this in a WHERE clause
SELECT *
FROM T
WHERE %%physloc%% = 0x2926020001000100
SQL Server will not directly seek to the specified row. Instead it will do a full table scan, evaluate %%physloc%% for each row and return the one that matches (if any do).
To reverse the process carried out by the 2 previously mentioned functions and get the binary(8) value corresponding to known File,Page,Slot values the below can be used.
DECLARE #FileId int = 1,
#PageId int = 338,
#Slot int = 3
SELECT CAST(REVERSE(CAST(#PageId AS BINARY(4))) AS BINARY(4)) +
CAST(REVERSE(CAST(#FileId AS BINARY(2))) AS BINARY(2)) +
CAST(REVERSE(CAST(#Slot AS BINARY(2))) AS BINARY(2))
I have to dedupe a very big table with many columns and speed is important. Thus I use this method which works for any table:
delete T from
(select Row_Number() Over(Partition By BINARY_CHECKSUM(*) order by %%physloc%% ) As RowNumber, * From MyTable) T
Where T.RowNumber > 1
If you want to uniquely identify a row within the table rather than your result set, then you need to look at using something like an IDENTITY column. See "IDENTITY property" in the SQL Server help. SQL Server does not auto-generate an ID for each row in the table as Oracle does, so you have to go to the trouble of creating your own ID column and explicitly fetch it in your query.
EDIT: for dynamic numbering of result set rows see below, but that would probably an equivalent for Oracle's ROWNUM and I assume from all the comments on the page that you want the stuff above.
For SQL Server 2005 and later you can use the new Ranking Functions function to achieve dynamic numbering of rows.
For example I do this on a query of mine:
select row_number() over (order by rn_execution_date asc) as 'Row Number', rn_execution_date as 'Execution Date', count(*) as 'Count'
from td.run
where rn_execution_date >= '2009-05-19'
group by rn_execution_date
order by rn_execution_date asc
Will give you:
Row Number Execution Date Count
---------- ----------------- -----
1 2009-05-19 00:00:00.000 280
2 2009-05-20 00:00:00.000 269
3 2009-05-21 00:00:00.000 279
There's also an article on support.microsoft.com on dynamically numbering rows.
Check out the new ROW_NUMBER function. It works like this:
SELECT ROW_NUMBER() OVER (ORDER BY EMPID ASC) AS ROWID, * FROM EMPLOYEE
Several of the answers above will work around the lack of a direct reference to a specific row, but will not work if changes occur to the other rows in a table. That is my criteria for which answers fall technically short.
A common use of Oracle's ROWID is to provide a (somewhat) stable method of selecting rows and later returning to the row to process it (e.g., to UPDATE it). The method of finding a row (complex joins, full-text searching, or browsing row-by-row and applying procedural tests against the data) may not be easily or safely re-used to qualify the UPDATE statement.
The SQL Server RID seems to provide the same functionality, but does not provide the same performance. That is the only issue I see, and unfortunately the purpose of retaining a ROWID is to avoid repeating an expensive operation to find the row in, say, a very large table. Nonetheless, performance for many cases is acceptable. If Microsoft adjusts the optimizer in a future release, the performance issue could be addressed.
It is also possible to simply use FOR UPDATE and keep the CURSOR open in a procedural program. However, this could prove expensive in large or complex batch processing.
Caveat: Even Oracle's ROWID would not be stable if the DBA, between the SELECT and the UPDATE, for example, were to rebuild the database, because it is the physical row identifier. So the ROWID device should only be used within a well-scoped task.
If you want to permanently number the rows in the table, Please don't use the RID solution for SQL Server. It will perform worse than Access on an old 386. For SQL Server simply create an IDENTITY column, and use that column as a clustered primary key. This will place a permanent, fast Integer B-Tree on the table, and more importantly every non-clustered index will use it to locate rows. If you try to develop in SQL Server as if it's Oracle you'll create a poorly performing database. You need to optimize for the engine, not pretend it's a different engine.
also, please don't use the NewID() to populate the Primary Key with GUIDs, you'll kill insert performance. If you must use GUIDs use NewSequentialID() as the column default. But INT will still be faster.
If on the other hand, you simply want to number the rows that result from a query, use the RowNumber Over() function as one of the query columns.
if you just want basic row numbering for a small dataset, how about someting like this?
SELECT row_number() OVER (order by getdate()) as ROWID, * FROM Employees
From http://vyaskn.tripod.com/programming_faq.htm#q17:
Oracle has a rownum to access rows of a table using row number or row id. Is there any equivalent for that in SQL Server? Or how to generate
output with row number in SQL Server?
There is no direct equivalent to Oracle's rownum or row id in SQL
Server. Strictly speaking, in a relational database, rows within a
table are not ordered and a row id won't really make sense. But if you
need that functionality, consider the following three alternatives:
Add an IDENTITY column to your table.
Use the following query to generate a row number for each row. The following query generates a row number for each row in the authors
table of pubs database. For this query to work, the table must have a
unique key.
SELECT (SELECT COUNT(i.au_id)
FROM pubs..authors i
WHERE i.au_id >= o.au_id ) AS RowID,
au_fname + ' ' + au_lname AS 'Author name'
FROM pubs..authors o
ORDER BY RowID
Use a temporary table approach, to store the entire resultset into a temporary table, along with a row id generated by the IDENTITY()
function. Creating a temporary table will be costly, especially when
you are working with large tables. Go for this approach, if you don't
have a unique key in your table.
ROWID is a hidden column on Oracle tables, so, for SQL Server, build your own. Add a column called ROWID with a default value of NEWID().
How to do that: Add column, with default value, to existing table in SQL Server
Please see http://msdn.microsoft.com/en-us/library/aa260631(v=SQL.80).aspx
In SQL server a timestamp is not the same as a DateTime column. This is used to uniquely identify a row in a database, not just a table but the entire database.
This can be used for optimistic concurrency. for example
UPDATE [Job] SET [Name]=#Name, [XCustomData]=#XCustomData WHERE ([ModifiedTimeStamp]=#Original_ModifiedTimeStamp AND [GUID]=#Original_GUID
the ModifiedTimeStamp ensures that you are updating the original data and will fail if another update has occurred to the row.
I took this example from MS SQL example and you can see the #ID can be interchanged with integer or varchar or whatever. This was the same solution I was looking for, so I am sharing it. Enjoy!!
-- UPDATE statement with CTE references that are correctly matched.
DECLARE #x TABLE (ID int, Stad int, Value int, ison bit);
INSERT #x VALUES (1, 0, 10, 0), (2, 1, 20, 0), (6, 0, 40, 0), (4, 1, 50, 0), (5, 3, 60, 0), (9, 6, 20, 0), (7, 5, 10, 0), (8, 8, 220, 0);
DECLARE #Error int;
DECLARE #id int;
WITH cte AS (SELECT top 1 * FROM #x WHERE Stad=6)
UPDATE x -- cte is referenced by the alias.
SET ison=1, #id=x.ID
FROM cte AS x
SELECT *, #id as 'random' from #x
GO
You can get the ROWID by using the methods given below :
1.Create a new table with auto increment field in it
2.Use Row_Number analytical function to get the sequence based on your requirement.I would prefer this because it helps in situations where you are you want the row_id on ascending or descending manner of a specific field or combination of fields
Sample:Row_Number() Over(Partition by Deptno order by sal desc)
Above sample will give you the sequence number based on highest salary of each department.Partition by is optional and you can remove it according to your requirements
Please try
select NEWID()
Source: https://learn.microsoft.com/en-us/sql/t-sql/data-types/uniqueidentifier-transact-sql