sqlite3: how to select same row twice when there is a match? - sqlite

Create SOF.SQL
CREATE TABLE "android_metadata" ("locale" TEXT DEFAULT 'en_US');
INSERT INTO "android_metadata" VALUES ('en_US');
CREATE TABLE main.t_def (
_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
word TEXT(20) not null,
word_def TEXT(20) not null
);
insert into t_def (word, word_def) values ('ball','spherical object');
insert into t_def (word, word_def) values ('cat','feline');
insert into t_def (word, word_def) values ('dog','common housekept');
CREATE TABLE main.t_a (
_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
corr_answer TEXT(20) not null,
user_answer TEXT(20) not null,
is_correct INTEGER not null
);
insert into t_a (user_answer, corr_answer, is_correct) values ('ball','cat',0);
insert into t_a (user_answer, corr_answer, is_correct) values ('dog','dog',1);
.exit
Then run:
sqlite3 foo.db < SOF.SQL
I want a result set that is:
ball|spherical object|cat|feline|0
This is the closest I have gotten:
select t_def.word, t_def.word_def from t_def, t_a where t_a.is_correct=0 and t_a.corr_answer=t_def.word;

To get values from two rows, you need two instances of the table:
SELECT t_a.user_answer,
user_def.word_def AS user_word_def,
t_a.corr_answer,
corr_def.word_def AS corr_word_def,
t_a.is_correct
FROM t_a
JOIN t_def AS user_def ON t_a.user_answer = user_def.word
JOIN t_def AS corr_def ON t_a.corr_answer = corr_def.word
WHERE NOT t_a.is_correct

Related

Insert Data into SQL Table with primary key column

I have a table in a SQL Server database and an R script that appends data to that tabl.
The db table contains a primary key ("ID"), which is just a scope_identity field
When I try to append the table into that location, I keep running into the following error
> sqlSave(Conn[["DbCon"]],
+ dat = OutputDataFinal,
+ tablename = "DataSci_StandardTransferPriority",
+ verbose = TRUE,
+ append = TRUE,
+ rownames = FALSE)
Query:
INSERT INTO "DataSci_StandardTransferPriority" (
"ID", "LeadSourceName", "AgeCategory", "ZipColor", "LeadCount_Sum",
"OB_TotalDials_Sum", "ContactRate", "TransferRate", "HypTransfers", "LaborCPT",
"MarketingCpt", "CloseRate", "PDLTR", "Policy_Count_Sum", "InboundDials_Sum",
"LeadCost_Sum", "PPT", "PPH", "ContactRateXCloseRate", "ContactRateXCloseRateTarget",
"ModelValue", "SourcePriority", "InsertTS"
)
VALUES ( ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? )
Error in odbcUpdate(channel, query, mydata, coldata[m, ], test = test, :
missing columns in 'data'
How can I append and ignore the issue with the primary key?
In standard INSERT operation dont specify identity column. It automatically provides next incremental identity value. For example:
CREATE TABLE #TempTable (
[ID] [bigint] NOT NULL IDENTITY(1, 1) PRIMARY KEY,
[Column1] [varchar](50) NULL,
[Column2] [decimal](19, 3) NOT NULL
);
INSERT INTO #TempTable (
[Column1],
[Column2]
)
VALUES
('first insert', 50.2),
('second insert', 84.2);
SELECT *
FROM #TempTable
DROP TABLE #TempTable;
The result was:
ID
Column1
Column2
1
first insert
50.200
2
second insert
84.200
If you want insert on identity column any way - enable IDENTITY_INSERT. But be care for data integrity issues.
CREATE TABLE #TempTable (
[ID] [bigint] NOT NULL IDENTITY(1, 1) PRIMARY KEY,
[Column1] [varchar](50) NULL,
[Column2] [decimal](19, 3) NOT NULL
);
INSERT INTO #TempTable (
[Column1],
[Column2]
)
VALUES ('first insert', 50.2);
SET IDENTITY_INSERT #TempTable ON;
INSERT INTO #TempTable (
[ID],
[Column1],
[Column2]
)
VALUES
(4, 'second insert', 84.63),
(2, 'third insert', 99.56);
SET IDENTITY_INSERT #TempTable OFF;
INSERT INTO #TempTable (
[Column1],
[Column2]
)
VALUES ('four insert', 100.32);
SELECT *
FROM #TempTable
DROP TABLE #TempTable;
And the result:
ID
Column1
Column2
1
first insert
50.200
2
third insert
99.560
4
second insert
84.630
5
four insert
100.320

How to move column from referenced table to referrer table using only SQLite language dialect?

I have following table structure in SQLite database:
CREATE TABLE A (id integer primary key, name text, room Integer);
CREATE TABLE B (id integer primary key, idA integer not null, code blob, FOREIGN KEY(idA) REFERENCES A(id));
For each record in A there are 1 to n records in B that refers it. Desired table structure is:
CREATE TABLE A (id integer primary key, name text);
CREATE TABLE B (id integer primary key, idA integer not null, code blob, room Integer, FOREIGN KEY(idA) REFERENCES A(id));
So, I would like to transer room column from A to B without data loss: recreate table A without room column, delete duplicates from A, add room column to B, set it depends on what values were in referenced A records room columns (original A table) and reassign idA for B records.
Is it possible using only SQLite and if it is, how to do this, using only SQLite?
Thank you!
have a look at http://sqlfiddle.com/#!5/e26e2/1 .
creating the databases :
CREATE TABLE A (id integer primary key, name text, room Integer);
CREATE TABLE B (id integer primary key, idA integer not null, code blob, FOREIGN KEY(idA) REFERENCES A(id));
Fill in some test data :
insert into A (id, name, room) values (1, "azerty", 123) ;
insert into A (id, name, room) values (2, "querty", 456) ;
insert into B (id, idA, code) values (10, 1, "code 1") ;
insert into B (id, idA, code) values (15, 1, "code 1b") ;
insert into B (id, idA, code) values (20, 1, "code 1c") ;
insert into B (id, idA, code) values (25, 2, "code 2") ;
insert into B (id, idA, code) values (30, 3, "code 3") ;
copy the wrong table layouts to tables we will later drop :
alter table B rename to old_B ;
alter table A rename to old_A ;
Create tables according the correct layout :
CREATE TABLE A (id integer primary key, name text);
CREATE TABLE B (id integer primary key, idA integer not null, code blob, room Integer, FOREIGN KEY(idA) REFERENCES A(id));
Copy selected data from old_A into A :
INSERT OR REPLACE INTO A ( id, name)
SELECT id, name FROM old_A ;
fill B with an inner join to "line up" room with correct idA :
INSERT OR REPLACE INTO B ( id, idA, code, room)
SELECT old_B.*, old_A.room FROM old_B INNER JOIN old_A ON old_B.idA = old_A.id ;
drop the old tables
DROP TABLE old_A ;
DROP TABLE old_B ;

SQlite Error: no such table: while using join

I have two tables joined together with third many-to-many relation. I'm trying to do select, but SQLite (version 3.11.0) keep telling me that my one of them doesn't exist which is not true! I have no idea what am I doing wrong.
Here are my tables:
DROP TABLE IF EXISTS traits;
CREATE TABLE traits(
trait_id INTEGER UNIQUE NOT NULL CHECK(TYPEOF(trait_id) = 'integer'),
name VARCHAR UNIQUE NOT NULL CHECK(TYPEOF(name) = 'text'),
uri VARCHAR UNIQUE NOT NULL CHECK(TYPEOF(uri) = 'text'),
PRIMARY KEY (trait_id)
);
DROP TABLE IF EXISTS trait_categories;
CREATE TABLE trait_categories(
trait_category_id INTEGER UNIQUE NOT NULL CHECK(TYPEOF(trait_category_id) = 'integer'),
efo_id VARCHAR UNIQUE NOT NULL CHECK(TYPEOF(efo_id) = 'text'),
name VARCHAR UNIQUE NOT NULL CHECK(TYPEOF(name) = 'text'),
uri VARCHAR UNIQUE NOT NULL CHECK(TYPEOF(uri) = 'text'),
PRIMARY KEY (trait_category_id)
);
DROP TABLE IF EXISTS trait_categories_traits;
CREATE TABLE trait_categories_traits(
trait_category_id INTEGER NOT NULL CHECK(TYPEOF(trait_category_id) = 'integer'),
trait_id INTEGER NOT NULL CHECK(TYPEOF(trait_id) = 'integer'),
FOREIGN KEY (trait_category_id) REFERENCES trait_categories(trait_category_id),
FOREIGN KEY (trait_id) REFERENCES traits(trait_id)
);
Here is my SELECT which fails:
SELECT trait_categories.name, traits.name
FROM trait_categories JOIN trait_categories_traits ON trait_categories_traits.trait_category_id = trait_categories.trait_category_id
JOIN traits.trait_id ON trait_categories_traits.trait_id = traits.trait_id;
SQLite say:
sqlite> select trait_id from traits limit 1;
663
sqlite> SELECT trait_categories.name, traits.name
...> FROM trait_categories JOIN trait_categories_traits ON trait_categories_traits.trait_category_id = trait_categories.trait_category_id
...> JOIN traits.trait_id ON trait_categories_traits.trait_id = traits.trait_id;
Error: no such table: traits.trait_id
Please help.
JOIN joins two tables, so it wants two table names.
But traits.trait_id is not a table name.
It appears you wanted to join the traits table, so remove the .trait_id. (And when both columns have the same name, using USING is simpler.)
SELECT ...
FROM trait_categories
JOIN trait_categories_traits USING (trait_category_id)
JOIN traits USING (trait_id);

Get names for IDs in two columns in one from another table

I have two tables:
CREATE TABLE tElements (
elementID INTEGER,
name TEXT,
area TEXT,
zone TEXT,
voltageLevel TEXT,
mRID TEXT
);
CREATE TABLE tCAResults (
timestamp INTEGER NOT NULL,
outageElementID INTEGER NOT NULL,
monitoredElementID INTEGER NOT NULL,
preOutageLoading DOUBLE NOT NULL,
postOutageLoading DOUBLE NOT NULL
);
How can I create query where id's of outageElementID and monitoredElementID from table tCAResult would be displayed as names from table tElements?
I have been searching for a whole day but couldn't find the answer. The closest I found is this but can't work it out
A simple join or two will do the job:
select tc.timestamp, oe.name as outageElement, me.name as monitoredElement
from tCAResults tc
join tElements oe on (oe.elementID = tc.outageELementID)
join tElements me on (me.elementID = tc.monitoredElementID);

Get result from different tables - join

I have following tables in my DB
CREATE TABLE [author_details] (
[_id] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[name] TEXT NOT NULL,
[surname] TEXT NOT NULL,
[middle_name] TEXT NULL
);
CREATE TABLE [authors] (
[_id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
[book_id] INTEGER NOT NULL,
[author_id] INTEGER NOT NULL
);
CREATE TABLE [books] (
[_id] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[title] TEXT NOT NULL,
[publisher_id] INTEGER NOT NULL,
[isbn] VARCHAR(10) UNIQUE NULL,
[ean] VARCHAR(13) UNIQUE NULL,
[pages] INTEGER DEFAULT '0' NULL,
[year] INTEGER NOT NULL,
[edition] TEXT NULL
);
CREATE TABLE [publishers] (
[_id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
[name] TEXT NOT NULL
);
I want a list of all books with details, I've used following query:
SELECT b.title,b.isbn,b.ean,b.year,b.pages,b.edition,
CASE
WHEN ad.middle_name IS NULL
THEN ad.name||" "||ad.surname
ELSE ad.name||" "||ad.middle_name||" "||ad.surname
END AS author, p.name
FROM books AS b, authors AS a, author_details AS ad, publishers AS p
INNER JOIN authors, author_details, publishers ON b._id=a.book_id AND ad._id=a.author_id AND b.publisher_id=p._id
GROUP BY b._id
It returns All books but only one author for books with multiple authors. How to write the query to get all authors per book?
To get the values from all records in a group, you have to use the group_concat function:
SELECT b.title,b.isbn,b.ean,b.year,b.pages,b.edition,
group_concat(CASE
...
END) AS author, p.name
FROM ...
Additionally, you need to use the correct join syntax.
In your query, you are joining every table twice, which results in lots up duplicate records.
There are two equivalent syntaxes for joins.
Either use a plain list of tables, and WHERE:
...
FROM books AS b,
authors AS a,
author_details AS ad,
publishers AS p
WHERE b._id = a.book_id
AND a.author_id = ad._id
AND b.publisher_id = p._id
...
or use the JOIN operator for each join, with a join condition for each join:
...
FROM books AS b
JOIN authors AS a ON b._id = a.book_id
JOIN author_details AS ad ON a.author_id = ad._id
JOIN publishers AS p ON b.publisher_id = p._id
...
Try to use group_concat():
SELECT b.title,b.isbn,b.ean,b.year,b.pages,b.edition,
GROUP_CONCAT(CASE
WHEN ad.middle_name IS NULL
THEN ad.name||" "||ad.surname
ELSE ad.name||" "||ad.middle_name||" "||ad.surname
END) AS author,
p.name
FROM
.........

Resources