I am trying to understand what's the best way to get specific rows out of a table in one query.
Let's say my table columns are:
Name, age, country
Let's say it has 1000 rows. I then have an array of indexes that represent the rows:
[2,10,20,34,50,120,400, 410,444,810]
How can I get the corresponding names? So, [name at row 2, name at row 10, ....]
I saw something like this online:
SELECT * FROM `posts` WHERE `id` IN (5,6,7,8,9,10)
but, I don't have an id column...do I need to manipulate the table or DB before pulling something like that off?
The following would work (to a fashion) :-
SELECT * FROM `posts` WHERE rowid IN (5,6,7,8,9,10)
This is because generally the ubiquitous id column is generally an alias of the special (normally hidden) rowid column.
That is a table that is not defined using WITHOUT ROWID will have a rowid column with automatically generated id's (unless the rowid is specified or implicitly specified via a column that is an alias of the rowid column).
An alias of the rowid column is defined by specifying ?? INTEGER PRIMARY KEY (where ?? represents a valid column name (often id)). The keyword AUTOINCREMENT can compliment INTEGER PRIMARY KEY and it adds a constraint that the generated id (i.e. the rowid) MUST increase, whilst without unused lower numbers can be used (only relevant when the highest id is 9223372036854775807). With AUTOINCREMENT, should this highest id be reached then an SQLITE_FULL exception will be encountered (without an attempt will be made to select a lower free number first).
The above is a summary of some of the points from SQLite Autoincrement.
Example Demonstration
Consider the following (the last two SELECT queries being the equivalent of the answer) :-
DROP TABLE IF EXISTS rowid_demo1;
DROP TABLE IF EXISTS rowid_demo2;
CREATE TABLE IF NOT EXISTS rowid_demo1 (name TEXT, age INTEGER, country TEXT);
CREATE TABLE IF NOT EXISTS rowid_demo2 (id_column INTEGER PRIMARY KEY, name TEXT, age INTEGER, country TEXT);
INSERT INTO rowid_demo1 (name,age,country) VALUES
('Fred',22,'England'),('Mary',18,'Scotland'),('Heather',19,'Wales');
INSERT INTO rowid_demo2 (name,age,country) VALUES
('Fred',22,'England'),('Mary',18,'Scotland'),('Heather',19,'Wales');
SELECT *,rowid as rowid_column FROM rowid_demo1;
SELECT *,rowid as rowid_column FROM rowid_demo2;
INSERT INTO rowid_demo1 (rowid,name,age,country) VALUES
(100,'George',21,'France');
INSERT INTO rowid_demo2 (rowid,name,age,country) VALUES
(100,'George',21,'France');
SELECT *,rowid as rowid_column FROM rowid_demo1;
SELECT *,rowid as rowid_column FROM rowid_demo2;
-- Ridiculous to do the following but ??????
INSERT INTO rowid_demo2 (rowid,id_column,name,age,country) VALUES
(500,501,'Beth',20,'Spain');
SELECT *,rowid as rowid_column FROM rowid_demo1;
SELECT *,rowid as rowid_column FROM rowid_demo2;
SELECT *,rowid AS rowid_column FROM rowid_demo1 WHERE rowid IN(2,3,100);
SELECT *,rowid AS rowid_column FROM rowid_demo2 WHERE rowid IN(2,3,100,501);
Explanation
This :-
creates 2 tables (the same other than rowid_demo2 has an alias of the rowid column) and - loads some data
runs 2 SELECT queries (one for each table) to shows the rows including the rowid column. (results 1 and 2)
some more data is loaded. However, this time by specifying values for the rowid
The same 2 queries are run (results 3 and 4)
a ridiculous row is added to the 2nd table (both the rowid and it's alias are given values)
Again the same 2 queries are run (results 5 and 6)
Queries equivalent to the answer are run (results 7 and 8).
Demonstration results :-
So I have two tables, I want to have a column on one table increment or decrement as items on another table are added or deleted, the link is the FOREIGN key.
I have two triggers but I'm not sure if they would work.
So I'd like some confirmation as to whether or not I'm barking up the right tree,if I'm going wrong or not an any fixes improvements?
SQL=
CREATE TABLE IF NOT EXISTS Agents(
Id INTEGER PRIMARY KEY,
Name TEXT,
Office_Count INT,
);
CREATE TABLE IF NOT EXISTS Branches(
Id INTEGER PRIMARY KEY,
Street_Address TEXT,
City TEXT,
Postcode TEXT,
Agents_Id INTEGER,
FOREIGN KEY(Agents_Id) REFERENCES Branches(Id)
);
CREATE TRIGGER Branches_Count_Increment AFTER INSERT ON Branches
BEGIN
UPDATE Agents SET
Office_Count=(MAX(Office_Count)+ 1 FROM Branches Where Agents_Id=Agents.Id) WHERE Id=NEW.Id;
END;
CREATE TRIGGER Branches_Count_Decrement AFTER DELETE ON Branches
BEGIN
UPDATE Agents SET
Office_Count=(MAX(Office_Count)- 1 FROM Branches Where Agents_Id=Agents.Id) WHERE Id=NEW.Id;
END;
You are barking in the general direction of an okay tree.
But the outer WHEREs use the wrong ID: the agents table must use an agent ID, which NEW.id is not.
And the MAX is not needed, and a subquery would need a SELECT.
UPDATE Agents
SET Office_Count = Office_Count + 1
WHERE Id = NEW.Agents_Id;
I am developing a .ASPX page with following design
Firstname
Lastname
Address
City
Mobile
This is represented to user with labels and textboxes.
When user clicks on Save button, data is saved in SQL Server 2008 Express database table.
Table has following schema
RecordNo-int(PK)
Firstname-nvarchar(50)
Lastname-nvarchar(50)
Address-nvarchar(500)
City-nvarchar(50)
Mobile-nvarchar(12)
At the time of page loading, I also display recordno to user.
This record number is generated based on how many records are there in the table.
I get the number of records and just increment it by 1 and put it against RecordNo.
Now, if this is happening on one PC, it works fine.
First entry will be represented with RecordNo 1
and so on.
But if, there is no record in the table, and the same page is opened by 4 different users at the same time, then all will
be represented with RecordNo 1.
and then, user who first click save button, will be able to save the data perfectly.
But other three users will encounter error, because they are entering information with RecordNo 1, which is already entered.
How do i overcome this?
Each new entry should be given new and unique RecordNo.
Is there any way i can do this?
Why to take headache of showing the number of entries you just set the primary key column to Identity(1,1) which will increment that column value by 1 every time a new row is inserted. This is how 'n' number of user will be able to make entries concurrently.
Set an Identity Cloumn as :
RecordNo int Identity(1,1) Primary Key
In Identity(1,1) first 1 is Starting Value and Other is Increment Value.
Use the code below if you don't want to use Identity:
SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY RecordNo ASC) AS RecordNumber,
FirstName,LastName,Address,City,Mobile from yourTableName) AS RecordNo
Make RecordNo an IDENTITY(1,1) field and forget about all your logic to generate the key. IDENTITY does this for you automatically.
If you require you can call SCOPE_IDENTITY() after the record is inserted to capture the generated value.
I have a script below - I dont know if it will produce the same effect as auto increment. When i begin inserting rows into my database, i dont want to insert the id. I want the database to generate and insert them automatically when i insert non-id rows.
CREATE TABLE myschema.mytable
(id NUMBER PRIMARY KEY NOT NULL,
name VARCHAR2(30));
CREATE SEQUENCE myschema.test1_sequence
START WITH 1
INCREMENT BY 1;
create or replace trigger myschema.auto_increment
before insert on myschema.mytable
for each row
begin
select test1_sequence.nextval into :new.id from dual;
end;
/
Yes it will work, except that you don't have to use
id NUMBER PRIMARY KEY NOT NULL
because PRIMARY KEY already contains the NOT NULL constraint, so
id NUMBER PRIMARY KEY
is enough.
Is there a one-statement select-and-update (or update-and-select) method in SQLite?
A trigger can invoke select, but that doesn't allow update to be used in an expression:
CREATE TABLE id ( a integer );
CREATE TRIGGER idTrig AFTER UPDATE ON id BEGIN SELECT old.a FROM id; END;
INSERT INTO id VALUES ( 100 );
INSERT INTO test VALUES ( (UPDATE id SET a=a+1) ); -- syntax error
(Is a triggered select only accessible via the C API?)
I generate object IDs for several databases from a single ID database (with a single row for the next available ID). I'd like to select-and-update on the ID db in one statement, so that concurrent db connections which attach the ID db won't have trouble with this (where two connections could insert before either updates):
INSERT INTO tab VALUES ( (SELECT uuid||oid AS oid FROM id.tab), ... );
UPDATE id.tab SET oid = oid+1;
I'll start with the prerequisite nag: why not use GUIDs? They don't require central authority and are thus more efficient and easier to work with.
If you really need a central ID store, you can make the ID an autoincrement and fetch it with SELECT last_insert_rowid(). If you have to generate your own IDs, then make the ID column a primary key, so you can generate the ID, INSERT it, and retry if the INSERT fails.
This discussion presents two possible solutions:
http://www.mail-archive.com/sqlite-users#sqlite.org/msg10705.html