unique constraint grouped by other column - sql

I have a table which has a father_id column and a serial_number column,
I want to create a unique constraint on the serial number by the father id.
Meaning rows that have the same father_id can't have the same serial_number, but rows that have a different father_id can have the same serial_number.

To rephrase the requirement, you want the combination of father_id and serial_number to be unique. Once the requirement is phrased like that, it's easier to translate to SQL:
ALTER TABLE mytable
ADD CONSTRAINT mytable_unq UNIQUE (father_id, serial_number);

This looks like a compound unique key. Here is one way to do it with a unique index:
create unique index myindex on mytable(father_id, serial_number);
Or in a create table statement, with a unique constraint:
create table mytable (
father_id int,
serial_number int,
constraint myconstraint unique (father_id, serial_number)
);

Related

Foreign key without correspondence in the referenced table

I'm trying to come up with a solution for an exercise in which I have to create 3 tables: one for employees, one for projects, and one for projects and employees, in which I have to insert the employee's ID and associate with a project ID. In the project_employee table, since it has only 2 columns that reference other tables, I thought I could set them bot as foreign keys, like this:
CREATE TABLE employee_project
(
id_employee numeric FOREIGN KEY REFERENCES employee(id_employee),
id_project numeric FOREIGN KEY REFERENCES project(id_project)
)
Then I stumbled upon a problem: when inserting values on the 3 tables, I noticed that one of the employee's ID number was 4, but on the table employee there was no line with ID 4. Of course, this line wasn't created, but I want to understand: is there a way I could create a line whose ID has no matching record in the referenced table? Could it be a possible mistake in the question, or is there something I'm missing? Thanks in advance for your time!
If there is no rows in employee table with id_employee value 4 then there should not be rows in employee_project table with id_employee value 4. SQL Server will give you an error like below:
The INSERT statement conflicted with the FOREIGN KEY constraint "FK__employee__id__75F77EB0". The conflict occurred in database "test", table "dbo.employee", column 'id_employee'.
But if you want to create employee_project with composite primary key on both the column you can try this:
CREATE TABLE employee_project
(
id_employee int not null,
id_project int not null,
primary key(id_employee, id_project )
)

SQL Insert into table with 2 non-unique primary keys

I have a table that I need to insert data into.
The table Sales has 4 columns
CustomerValueType_id (int)
Customer_id (int)
Value (NVARCHAR)
Customer_name (NVARCHAR)
The CustomerValueType_id, Customer_id are foreign keys that are not-unique, CustomerValueType_id matches to a value type, while Customer_id matches to the Customer_name.
I need to add additional customer data into the Valuecolumn but how do I ensure that the data matches to the correct CustomerValueType_id and Customer_id and each customer name has to be repeated in the Customer_name
Sales Table
You are trying to do denormalization.
Ideally, in the normalized design, you will just store, parent_ids in
the child table. If you want to see parent_name fields, you have to
get them based on JOIN conditions.
But, here as you are storing both id, name in the child table, I would suggest you to create composite Foreign key in the child table, so that the combination is always present. Also, make this combination as composite primary key in the parent table.
-- Parent Table PRIMARY KEY
ALTER TABLE dbo.CustomerValueType
ADD CONSTRAINT PK_CustomerValueType
PRIMARY KEY CLUSTERED (CustomerValueType_id, Value);
GO
--Child Table FOREIGN KEY
ALTER TABLE dbo.Sales
ADD CONSTRAINT FK_Sales_CustomerValueType
FOREIGN KEY (CustomerValueType_id,Value)
REFERENCES dbo.CustomerValueType(CustomerValueType_id,Value);
GO

How to create constraint 'EXCLUDE' or 'Unique' with column group and predicate in Postresql?

I have the table:
create table mytable (
id bigint not null primary key,
org int,
post int,
op int,
staff boolean
)
and i need create two constrains:
unique org and post if staff is true
unique org, post and op if staff is false
But UNIQUE contraint doesn't have predicate (clause where). I want to use EXCLUDE constraint as has clause where, but EXCLUDE doesn't support column group in the same operator. I.e :
constraint stafUnique EXCLUDE ( (org,post) with in) where (staff = true)
gives an error.
How to implement it?
Thanks.
You can use create unique index in lieu of constraint
create unique index ix_staff_true on mytable(org, post) where staff;
create unique index ix_staff_false on mytable(org, post, op) where not staff;

Foreign key constraint with some where clause in SQL Server

I have two tables, one with columns accountid, category, code, name, desc and the other with columns id, accountid, code, reason, desc, active.
Is there any way I can create a constraint such that code in the second table contains only values of code that are in first table with condition where category is somevalue?
One method is a little trick. First, create a unique index on (category, code) in the first table:
create unique index unq_table1_category_code on table1(category, code)
Then create a computed column in table2:
alter table table2 add category as ('somevalue') persisted;
Then create the foreign key relationship:
alter table table2 add constraint fk_somevalue_code
foreign key (category, code) references table1(category, code);
ALTER TABLE table2 WITH CHECK
ADD CONSTRAINT CK_table2category CHECK (category = 'somevalue'),
CONSTRAINT FK_table2code FOREIGN KEY (code) REFERENCES table1 (code);

Foreign Keys to Composite Key

If I have a table where AId is the primary key and BId and CId are foreign keys referencing their tables. I need to make the combination of BId and CId unique.
How would I alter the table to make the combination unique?
Thanks
AId BId CId Notes Date
=== === === ===== ====
1 200 1 Random 2/2/2005
2 201 2 ETC 2/8/2007
3 202 3 ETC 2/12/2012
You need to create a unique index or a unique constraint.
I generally prefer unique indexes as they are more flexible (can add included columns if desired) and they don't have to be uniquely named in the schema.
Example syntax for a unique index
CREATE UNIQUE NONCLUSTERED INDEX SomeIndex ON YourTable(BId, CId)
The order of BId, CId makes no difference to the uniqueness guarantee but does affect the queries the index can efficiently support (that way round supports looking up by Bid or BId, CId but not CId)
Try this:
ALTER TABLE myTable
ADD CONSTRAINT myConstraint
UNIQUE NONCLUSTERED
(
BId, CId
)
You can create unique indexes that are not the primary key. This will force the combination of BId and CId unique.
CREATE UNIQUE INDEX ix_ATable_AltUniqueIndex ON ATable(BId,CId)
Or you can create a unique constraint
ALTER TABLE ATable ADD CONSTRAINT uni_ATable UNIQUE (BId,CId)
Create a unique constraint appears to create a unique index also.