PSQL unique constraint on two columns - sql

I have a table which I use to link two more tables together in a 1 to many relationship.
TableA
id
name
TableB
id
name
LinkTable
TableA_id
TableB_id
Basically, one of TableA can have many of TableB. Very simple. The problem I have now is to create a constraint that follows the rules of this relation ship as such:
LinkTable
TableA_id TableB_id
1 1
1 2
1 3
2 1
2 2
2 3
I want to create a unique constraint which combines both the columns together as the unique value. So in the link table above, with this new constraint, I can
INSERT INTO LinkTable (TableA_id, TableB_id) VALUES (1, 4);
INSERT INTO LinkTable (TableA_id, TableB_id) VALUES (1, 5);
INSERT INTO LinkTable (TableA_id, TableB_id) VALUES (2, 6);
INSERT INTO LinkTable (TableA_id, TableB_id) VALUES (3, 1);
With out any problems
And if I try to insert:
INSERT INTO LinkTable (TableA_id, TableB_id) VALUES (1, 1);
INSERT INTO LinkTable (TableA_id, TableB_id) VALUES (1, 3);
The constraint will fire because there is already a row with 1,1 and 1,3. How would I create a postgres constraint to do this? If i set a unique constraint to both rows, then I cannot have more then one TableA_id the same and more then one TableB_id the same.
What is the solution?

have you tried setting both columns as unique?
ALTER TABLE LinkTable
ADD CONSTRAINT LinkTable_Unique UNIQUE (TableA_id, TableB_id);

create table LinkTable (
TableA_id integer REFERENCES TableA(id),
TableB_Id integer REFERENCES TableB(id),
UNIQUE(tableA_id, tableB_id)
);

Related

SQL table with primary key over two columns and unique values in both columns

How to create a table in SQL with the following attributes?
The table has two columns A and B.
The primary key of the table is (A, B).
All values in A are unique. Pseudo code: (Count(A) == COUNT(SELECT DISTINCT A)).
All values in B are also unique.
CREATE TABLE IF NOT EXISTS myTable(
A VARCHAR(32) PRIMARY KEY NOT NULL, -- A HAS DISTINCT VALUES
B VARCHAR(32) NOT NULL -- B HAS DISTINCT VALUES
);
INSERT INTO myTable VALUES ('A1', 'B1') --> Add value
INSERT INTO myTable VALUES ('A1', 'B2') --> Do not add value
INSERT INTO myTable VALUES ('A2', 'B2') --> Add value
INSERT INTO myTable VALUES ('A3', 'B3') --> Add value
INSERT INTO myTable VALUES ('A4', 'B3') --> Do not add value
INSERT INTO myTable VALUES ('A4', 'B4') --> Add value
INSERT INTO myTable VALUES ('A5', 'B6') --> Add value
To define a compound PRIMARY KEY:
CREATE TABLE myTable
(
A VARCHAR(32) NOT NULL,
B VARCHAR(32) NOT NULL,
CONSTRAINT PK_AB primary key (A,B),
CONSTRAINT UQ_A UNIQUE(A),
CONSTRAINT UQ_B UNIQUE(B)
);
Please note: a table with just 2 columns with both columns in the primary key smells funny.

Create new records in one table-A and add as foreign key to table-B if the foreign key field in table-B is null -PostgresSQL

Table A and Table B look like shown below. The intention is to write an SQL script to run and update the tables. Table B has a foreign key to Table-A. If the field is null in Table B, then create a new record in Table-A and update Table B with that foreign key
It is expected to add two new records in Table A and add those foreign key in the Table B as per the above example. Thanks in advance
I wrote for you sample for do it.
But I don't know your business logic detail. You can change some solutions.
CREATE TABLE tablea (
id serial4 NOT NULL,
"name" varchar NULL,
CONSTRAINT tablea_pk PRIMARY KEY (id)
);
CREATE TABLE tableb (
id serial4 NOT NULL,
a_id int4 NULL,
"name" varchar NULL,
CONSTRAINT tableb_pk PRIMARY KEY (id)
);
INSERT INTO tableb (id, a_id, "name") VALUES(1, 100, 'b1');
INSERT INTO tableb (id, a_id, "name") VALUES(2, NULL, 'b2');
INSERT INTO tableb (id, a_id, "name") VALUES(3, NULL, 'b3');
INSERT INTO tableb (id, a_id, "name") VALUES(4, NULL, 'b4');
-- create function for inserting data into tablea and returning these id
CREATE OR REPLACE FUNCTION tablea_inserting()
RETURNS integer
LANGUAGE plpgsql
AS $function$
declare
ret int4;
begin
insert into tablea ("name") values ('test')
returning id into ret;
return ret;
end
$function$
;
-- After then you can update your tableb
update tableb set
a_id = tablea_inserting()
where a_id is null
select * from tableb;
Result:
id a_id name
1 100 b1
2 1 b2
3 2 b3
4 3 b4

UNIQUE constraint failed SQL

I want to create two Tables, but it does not work because of "UNIQUE constraint failed".
Can someone explain to me what is wrong with my querees?
CREATE TABLE A (
ka INT PRIMARY KEY,
a2 VARCHAR(1)
);
INSERT INTO A VALUES (1,'s');
INSERT INTO A VALUES (2,'s');
INSERT INTO A VALUES (3,'s');
INSERT INTO A VALUES (4,'m');
INSERT INTO A VALUES (5,'m');
INSERT INTO A VALUES (6,'b');
INSERT INTO A VALUES (7,'b');
INSERT INTO A VALUES (8,'b');
INSERT INTO A VALUES (9,'b');
CREATE TABLE B (
a2 VARCHAR(1),
b2 INT,
PRIMARY KEY (a2),
FOREIGN KEY (a2) REFERENCES A(a2)
);
INSERT INTO B VALUES ('s',12);
INSERT INTO B VALUES ('s',23);
INSERT INTO B VALUES ('s',34);
INSERT INTO B VALUES ('m',45);
INSERT INTO B VALUES ('m',56);
INSERT INTO B VALUES ('b',67);
INSERT INTO B VALUES ('b',78);
INSERT INTO B VALUES ('b',89);
INSERT INTO B VALUES ('b',90);
(Edited: there is more than one issue here.)
A primary key for table B must be unique. In your case, it needs to be something other than a2. If you need a primary key (usually you do just as a part of good design), you likely need a separate dedicated column.
Something like:
CREATE TABLE B (
kb INT,
a2 VARCHAR(1),
b2 INT,
PRIMARY KEY (kb),
--FOREIGN KEY (a2) REFERENCES A(a2) -- This is also an issue
);
INSERT INTO B VALUES (101, 's',12);
INSERT INTO B VALUES (102, 's',23);
INSERT INTO B VALUES (103, 's',34);
INSERT INTO B VALUES (104, 'm',45);
INSERT INTO B VALUES (105, 'm',56);
INSERT INTO B VALUES (106, 'b',67);
INSERT INTO B VALUES (107, 'b',78);
INSERT INTO B VALUES (108, 'b',89);
INSERT INTO B VALUES (109, 'b',90);
EDIT:
The second issue is that your foreign key from table B is referencing a non-unique column in table A. Foreign keys define a many-to-one relationship, but your data indicates a potentially many-to-many relationship. The first three "s" rows in table B each match all three "s" rows in table A. While you can define a JOIN in a query that matches ON B.a2 = A.a2, you can't use a foreign key to define this relationship.

PostgreSQL connections constraint

I have table with two columns, id1 and id2.
If i have for example foo-bar respectively in these columns,I need a constraint that forbids entry bar-foo.
Thanks!
CREATE TABLE mytable(
id1 integer,
id2 integer
);
CREATE UNIQUE INDEX ON mytable(least(id1, id2), greatest(id1, id2));
This should ddo the trick:
test=> INSERT INTO mytable VALUES (1, 2);
INSERT 0 1
test=> INSERT INTO mytable VALUES (1, 3);
INSERT 0 1
test=> INSERT INTO mytable VALUES (2, 1);
ERROR: duplicate key value violates unique constraint "mytable_least_greatest_idx"
DETAIL: Key ((LEAST(id1, id2)), (GREATEST(id1, id2)))=(1, 2) already exists.

How to avoid bad data entries in table through proper Key relationship?

I have 3 tables. widgets, widget types, widget type ID. I have created direct relationship between them. How can I avoid bad data going into Widget tables based on Widget_type and Widget_sub_Type. Please see my code. There is just one small thing missing.
Create table widgets (
Widget_ID int not null primary key,
Widget_type_ID int not null,
Widget_Sub_type_ID int,
Widget_Name varchar (50)
)
Create table Widget_Type (
Widget_Type_ID int not null primary key,
)
Create table Widget_Sub_type (
Widget_Sub_Type_ID int not null primary key,
Widget_Type_ID int not null
)
---adding foregin key constraints
Alter table widgets
ADD constraint FK_Widget_Type
FOREIGN KEY (Widget_type_ID)
References Widget_Type (Widget_type_ID)
Alter table widgets
ADD constraint FK_Widget_Sub_Type
FOREIGN KEY (Widget_Sub_type_ID)
References Widget_SUB_Type (Widget_SUB_type_ID)
Alter table widget_Sub_Type
ADD Constraint FK_Widget_Type_Alter
Foreign key (widget_Type_ID)
References Widget_Type (Widget_Type_ID)
---- insert values
insert Widget_Type values (1)
insert Widget_Type values (5)
insert Widget_Sub_type values (3,1)
insert Widget_Sub_type values (4,1)
insert Widget_Sub_type values (7,5)
insert Widget_Sub_type values (9,5)
-- This will error out which is correct
insert Widget_Sub_type values (5,6)
select * from Widget_Sub_type
select * from Widget_type
--Good
insert widgets (Widget_ID,Widget_Name, Widget_type_ID, Widget_Sub_type_ID)
values (1, 'TOY', 1, 3)
select * from widgets
--Good
insert widgets (Widget_ID,Widget_Name, Widget_type_ID, Widget_Sub_type_ID)
values (2, 'BatMan', 5, 7)
-- How to prevenet this, 3 is not sub_type_id of type_ID 5. This is bad data, It should not be inserted.
insert widgets (Widget_ID,Widget_Name, Widget_type_ID, Widget_Sub_type_ID)
values (3, 'Should Not', 5, 3)