I been trying to follow this example on how to build constraints in SQLite.
I created a table:
CREATE TABLE `users` (
`user_id` INTEGER NOT NULL DEFAULT 1 PRIMARY KEY AUTOINCREMENT,
`row_id` INTEGER NOT NULL,
unique (user_id, row_id)
)
Than I been trying to make an insertions:
insert into users(user_id, row_id) values(1, 13)
insert into users(user_id, row_id) values(2, 13)
On the second insertion query it failed with the next message:
UNIQUE constraint failed: users.user_id: insert into users(user_id,
row_id) values(2, 13)
I want to allow the next rows:
1,13
2,13
1,5
And disallow those
1,13
1,13
PRIMARY KEY is by design UNIQUE and NOT NULL so user_id has to be UNIQUE.
Then you have UNIQUE constraint on columns user_id and row_id.
You could use composed PRIMARY KEY:
CREATE TABLE `users` (
`user_id` INTEGER NOT NULL,
`row_id` INTEGER NOT NULL,
PRIMARY KEY (user_id, row_id)
);
INSERT INTO users(user_id, row_id) VALUES(1, 13);
INSERT INTO users(user_id, row_id) VALUES(2, 13);
INSERT INTO users(user_id, row_id) VALUES(1, 5);
INSERT INTO users(user_id, row_id) VALUES(1, 13);
-- Error: UNIQUE constraint failed: users.user_id, users.row_id
SqlFiddleDemo
Primary Key is causing the issue, once a column is defined as primary it cannot be duplicated. Please try dropping the Primary Key.
CREATE TABLE `users` (
`user_id` INTEGER AUTO INCREMENT NOT NULL DEFAULT 1,
`row_id` INTEGER NOT NULL,
unique (user_id, row_id)
)
Related
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
I need to retrieve events from table, with skills requirements and user engagements and skills.
For a project, I have :
an users table
a skills table with inheritance from others skills
an users_skills table with skills of users
an events table
an events_skills table with the quantity of a required skills for the events
an events_users table with users engagements on events
CREATE TABLE `users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` char(32) NOT NULL
);
CREATE TABLE `skills` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` char(64) NOT NULL,
`parent_id` int(11) unsigned DEFAULT NULL,
FOREIGN KEY (`parent_id`) REFERENCES `skills` (`id`)
);
CREATE TABLE `users_skills` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
`user_id` int(11) unsigned NOT NULL,
`skill_id` int(11) unsigned NOT NULL,
FOREIGN KEY (`user_id`) REFERENCES `users` (`id`),
FOREIGN KEY (`skill_id`) REFERENCES `skills` (`id`)
);
CREATE TABLE `events` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` char(64) NOT NULL
);
CREATE TABLE `events_skills` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
`event_id` int(11) unsigned NOT NULL,
`skill_id` int(11) unsigned NOT NULL,
`quantity` smallint unsigned NOT NULL,
FOREIGN KEY (`event_id`) REFERENCES `events` (`id`),
FOREIGN KEY (`skill_id`) REFERENCES `skills` (`id`)
);
CREATE TABLE `events_users` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
`event_id` int(11) unsigned NOT NULL,
`user_id` int(11) unsigned NOT NULL,
FOREIGN KEY (`event_id`) REFERENCES `events` (`id`),
FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
);
I want to retrieve all events, with skills requirments and users participation.
My first idea was to use LEFT JOIN :
SELECT e.id, e.name, es.skill_id, s.name skill_name, es.quantity,
eu.user_id, u.name user_name, us.skill_id user_skill_id,
uss.name user_skill_name
FROM events e
LEFT JOIN events_skills es ON es.event_id = e.id
LEFT JOIN skills s ON s.id = es.skill_id
LEFT JOIN events_users eu ON eu.event_id = e.id
LEFT JOIN users u ON u.id = eu.user_id
LEFT JOIN users_skills us ON us.user_id = u.id
LEFT JOIN skills uss ON uss.id = us.skill_id;
id name skill_id skill_name quantity user_id user_name user_skill_id user_skill_name
1 eve1 2 ski2 3 1 use1 2 ski2
1 eve1 3 ski2-2 1 1 use1 2 ski2
1 eve1 2 ski2 3 2 use2 NULL NULL
1 eve1 3 ski2-2 1 2 use2 NULL NULL
2 eve2 NULL NULL NULL NULL NULL NULL NULL
2 differents events, second without users and skills. First, with 2 users, first with one skills, seconds without skills, and finally, two skills requirements.
It work "fine", but it's verry ugly, and I think it can be very slow if an event or an user has too many skills.
Also, each event has a lot of lines, and it's difficult to sort them (if I want to display only 20 events...).
To improve, I think I can load all skills separately and remove the two LEFT JOIN for table skills.
But, can I merge all skills and quantity in one column, and users in others ? Did you have betters solutions/improvements ?
id name skills users
1 eve1 2,3;3,1 1,2;2,NULL
2 eve2 NULL NULL
Thanks for your help.
Another way to do what Thorsten suggested:
select e.*,
( SELECT group_concat(skill_id order by skill_id separator ',')
from events_skills
WHERE event_id = e.id
) AS skills,
( SELECT group_concat(user_id order by user_id separator ',' )
from events_users
WHERE event_id = e.id
) AS users
from events e
order by e.id;
Each subquery needs an extra join to get the "name" of the skill and user instead of the "id".
May I suggest you use the name of the skill as its id.
When you have a many-many mapping table, be sure to use the pair of ids as the PRIMARY KEY and have an INDEX in the opposite order. And don't have an AUTO_INCREMENT. Details: http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table
A result with skills and users as comma-separated strings is exactly how I would do this, too. Use GROUP_CONCAT for this.
select e.*, s.skills, u.users
from events e
left join
(
select event_id, group_concat(skill_id order by skill_id separator ',') as skills
from events_skills
group by event_id
) s on s.event_id = e.id
left join
(
select event_id, group_concat(user_id order by user_id separator ',') as users
from events_users
group by event_id
) u on u.event_id = e.id
order by e.id;
Actually, I have two tables Branch and Account_table and I want to insert the account_table values with a foreign key(bID) values which is primary key in Branch Table (bID) but I am getting errors while inserting values. Following is my code.
create type bank_branch as object(
bID varchar2(10),
street varchar2(20),
city varchar2(20),
zipcode varchar2(10),
bPhone varchar2(20))
not final
/
create table branch of bank_branch(
primary key (bID),
/
insert into branch values(
'601','XYZ Street','Orlando','OR112AB','024771169');
/
insert into branch values(
'620','Terrace Road','California','CL229JH','548711131');
/
insert into branch values(
'630','Miami Street','Miami','M21334A','9665411211');
/
create type account_type as object(
accNum int,
accType varchar2(15),
balance number,
bID varchar2(10),
interest number,
overdraftLimit number,
openDate DATE)
/
create table account_table of account_type(
primary key (accNum),
FOREIGN key (bID) REFERENCES branch(bID));
/
insert into account_table
select 'bID', b.BID
from branch b
where b.BID = 601,
'1001','current','630.87','0.009','400','10-Sep-14');
/
Thanks.
create type bank_branch as object(
bID varchar2(10),
street varchar2(20),
city varchar2(20),
zipcode varchar2(10),
bPhone varchar2(20))
not final
/
create table branch of bank_branch(
primary key (bID));
/
insert into branch values(
'601','XYZ Street','Orlando','OR112AB','024771169');
/
insert into branch values(
'620','Terrace Road','California','CL229JH','548711131');
/
insert into branch values(
'630','Miami Street','Miami','M21334A','9665411211');
/
create type account_type as object(
accNum int,
accType varchar2(15),
balance number,
bID varchar2(10),
interest number,
overdraftLimit number,
openDate DATE);
/
create table account_table of account_type(
primary key (accNum),
FOREIGN key (bID) REFERENCES branch(bID));
/
insert into account_table
select '1001','current','630.87',b.BID,'0.009','400','10-Sep-14'
from branch b
where b.BID = 601;
/
1 row(s) inserted.
I have used the same code as yours. Only the insert statement differs. It works fine for me.
I am trying to Connect Three tables. Two of them have Primary Keys which the Third is supposed to link to. I need this inbetween as it is linked to a fourth (but this Works fine). The code I have written is as follows:
CREATE TABLE CUSTOMERS(
CUSTOMER_ID INT(10) NOT NULL,
SURNAME CHAR(50) NOT NULL,
NAME CHAR(50) NOT NULL,
PRIMARY KEY (CUSTOMER_ID)
);
CREATE TABLE WORKSHOP(
WORKSHOP_ID INT(10) NOT NULL,
NAME CHAR(100) NOT NULL,
CHAIN_NAME CHAR(100),
CHAIN_ID INT(10),
CONTRACT_WORKSHOP CHAR(5) NOT NULL,
PRIMARY KEY (WORKSHOP_ID, CHAIN_ID)
);
CREATE TABLE CAR_DAMAGE(
DAMAGE_ID INT(10) NOT NULL,
CUSTOMER_ID INT(10) NOT NULL,
DATE INT(20) NOT NULL,
PLACE CHAR(128) NOT NULL,
WORKSHOP_ID INT(10) NOT NULL,
PRIMARY KEY (DAMAGE_ID, CUSTOMER_ID, WORKSHOP_ID, DATE, PLACE),
FOREIGN KEY (CUSTOMER_ID) REFERENCES CUSTOMERS (CUSTOMER_ID),
FOREIGN KEY (WORKSHOP_ID) REFERENCES WORKSHOP (WORKSHOP_ID)
);
INSERT INTO CUSTOMERS VALUES (1, "OLSEN", "TROND");
INSERT INTO CUSTOMERS VALUES (2, "JOHNSEN", "FELIX");
INSERT INTO CUSTOMERS VALUES (3, "SVINDAL", "AKSEL");
INSERT INTO CUSTOMERS VALUES (4, "BJORGEN", "MARIT");
INSERT INTO CUSTOMERS VALUES (5, "SVENDSON", "LISA");
INSERT INTO WORKSHOP VALUES (1, "BERTEL", "MOLLER", 1, "YES");
INSERT INTO WORKSHOP VALUES (2, "OLOF", "OLOF AUTO", 3, "NO");
INSERT INTO WORKSHOP VALUES (3, "J-AUTO", "MOLLER", 1, "YES");
INSERT INTO WORKSHOP VALUES (4, "SPEED", "BIRGER N. HAUG", 2, "YES");
INSERT INTO WORKSHOP VALUES (5, "RELAX AUTO", "MOLLER", 1, "YES");
INSERT INTO CAR_DAMAGE VALUES (1, 1, 10102008, "HELLERUD", 1);
INSERT INTO CAR_DAMAGE VALUES (2, 2, 14032015, "JAR", 2);
INSERT INTO CAR_DAMAGE VALUES (3, 3, 24052016, "LOMMEDALEN", 3);
INSERT INTO CAR_DAMAGE VALUES (4, 4, 31102017, "FLAKTVEIT", 4);
INSERT INTO CAR_DAMAGE VALUES (5, 5, 08062016, "STOCKHOLM", 5);
However, the problem occur as I get the error "foriegn key mismatch - CAR_DAMAGE referencing WORKSHOP.
I am using SQLite as I am forced to use it, given by my University.
Table WORKSHOP has a composite primary key (WORKSHOP_ID, CHAIN_ID). Any foreign key referencing that table must be a composite foreign key, consisting of the same two fields. Hence, you would need to add CHAIN_ID to table WORKSHOP and change your foreign key declaration to something like:
FOREIGN KEY (WORKSHOP_ID, CHAIN_ID) REFERENCES WORKSHOP (WORKSHOP_ID, CHAIN_ID)
[More generally, your primary keys seem, based on the information given, more complex than they need to be: why not just have WORKSHOP_ID as PK of WORKSHOP and DAMAGE_ID as PK of CAR_DAMAGE? But maybe you have good reasons.]
Thank you. This Method worked. Hence, when I proceeded, a New problem occured. The table CAR_DAMAGE is linked to a fourth table (Called DAMAGE_INFORMATION), With the code:
CREATE TABLE DAMAGE_INFORMATION(
DAMAGE_ID INT(10) NOT NULL,
DAMAGE_TYPE CHAR(100) NOT NULL,
DAMAGE_SIZE CHAR(50) NOT NULL,
SPEND INT(10) NOT NULL,
FOREIGN KEY (DAMAGE_ID) REFERENCES CAR_DAMAGE (DAMAGE_ID)
);
And I receive the same error as earlier, i.e. Foreign key mismatch "DAMAGE_INFORMATION" referencing "CAR_DAMAGE".
Is it not allowed to make a combination of 3 tables to 1, With different primary keys? The primary key of CAR_DAMAGE is:
PRIMARY KEY (DAMAGE_KEY, CUSTOMER_ID, WORKSHOP_ID)
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