How do I make a variable unique constraint? - unique

I in the table below, I need scientific_name to be unique except when d_taxlevel_id = 7. Then I need scientific_name and d_taxgroup_id to be unique. I am using PostgreSQL. Thank you for any help you can provide.
create table taxon(
taxon_id int not null primary key,
parent_taxon_id int not null references taxon(taxon_id),
scientific_name varchar(100) not null,
d_taxgroup_id int not null references d_taxgroup(d_taxgroup_id),
d_taxlevel_id int not null references d_taxlevel(d_taxlevel_id)
);
when d_taxlevel_id = 7
then
unique_genus_in_taxgroup unique(scientific_name, d_taxgroup_id)
else
unique_non-genus_sciname unique(scientific_name)

Use separate tables , one where you need unique and create a primary key accordingly. Second table would be for Id = 7 where you can allow duplicates

Related

Can't create table 'student.#sql-f40_3' (errno: 150)

Table 1
create table personal(
id int not null auto_increment unique,
name char(20) not null,
age int not null,
city varchar(20) not null default 'Delhi'
);
insert into personal(name,age,city) values
('anubhav',22,'delhi'),
('rohit',24,'agra');
Table 2
create table applications(
app_id int(5) not null auto_increment unique,
city varchar(10) not null default 'Delhi'
);
insert into applications(city) values
('kolkata'),
('mumbai'),
('mumbai'),
('delhi'),
('agra'),
('agra');
Then i apply foreign key here with the help of Alter command-
alter table personal add foreign key(city) references applications(app_id)
but i am getting an error: ERROR 1005 (HY000): Can't create table 'student.#sql-f40_3' (errno: 150)
MySQL specifies:
Conditions and Restrictions
1.Corresponding columns in the foreign key
and the referenced key must have similar data types. The size and sign
of fixed precision types such as INTEGER and DECIMAL must be the same.
The length of string types need not be the same. For nonbinary
(character) string columns, the character set and collation must be
the same.
2.MySQL requires indexes on foreign keys and referenced keys so that foreign key checks can be fast and not require a table scan. In the
referencing table, there must be an index where the foreign key
columns are listed as the first columns in the same order. Such an
index is created on the referencing table automatically if it does not
exist. This index might be silently dropped later if you create
another index that can be used to enforce the foreign key constraint.
index_name, if given, is used as described previously.
The data type must be the same.
You could do:
alter table personal add foreign key(city) references applications(city)
But, the columns on both tables should be indexed.
See here
you desing in not normalized
your personal table should only reference the id.
City name in the applications should be unique, so i added it in the create table, there is no need for two or more delhis in a table(see normalisation)
If you really want to use in personal the city name, you must like i already made refernece the coty name of appcations or define a KEY for that column.
Further the datatyoes of the columns must always be the saem in both table for the foreign key
create table personal(
id int not null auto_increment unique,
name char(20) not null,
age int not null,
city int not null default 0
);
create table applications(
app_id int not null auto_increment primary key,
city varchar(10) not null unique default 'Delhi'
);
alter table personal add foreign key(city) references applications(app_id)
You have small bugs such as not putting null in the insert for the autoincrement and if it is primary key you should not put not null.
Table personal
create table personal(
id int auto_increment primary key,
name char(20) not null,
age int not null,
city varchar(20) not null default 'Delhi'
);
insert into personal values (null,'anubhav',22,'delhi'),
(null,'rohit',24,'agra');
Table applications
create table applications(
app_id int(5) auto_increment primary key,
city varchar(10) not null default 'Delhi'
);
insert into applications values(null,'kolkata'),
(null,'mumbai'),
(null,'mumbai'),
(null,'delhi'),
(null,'agra'),
(null,'agra');
Alter table
alter table personal add foreign key(city) references applications(app_id)

Auto Generate Column from Foreign Key

Lets say I have the following table:
CREATE TABLE IF NOT EXISTS tbl_mg_accounts (
account_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,L,
holder_id INT NOT NULL,
FOREIGN KEY (holder_id) REFERENCES tbl_mg_holders(holder_id) ON UPDATE CASCADE ON DELETE CASCADE
);
I want to add another column that auto-fills but it's based on a column within the foreign table reference.
E.g.
CREATE TABLE IF NOT EXISTS tbl_mg_accounts (
account_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,L,
holder_id INT NOT NULL,
username VARCHAR(50) NOT NULL,
test_col VARCHAR(100) GENERATED ALWAYS AS CONCAT(tbl_mg_holders.holder_name, username) VIRTUAL,
FOREIGN KEY (holder_id) REFERENCES tbl_mg_holders(holder_id) ON UPDATE CASCADE ON DELETE CASCADE
);
This is giving me an error...
Perhaps the addition of below is a syntax issue or is this actually a limitation with MySQL/MariaDB?
test_col VARCHAR(100) GENERATED ALWAYS AS CONCAT(tbl_mg_holders.holder_name, username) VIRTUAL
Ok Yes this seems like a limitation.
I've instead created a VIEW for my requirements and let the backend process this way.

Best way to relate foreign key to parent

I don't dabble much in SQL design at all, so this might be a trivial question.
I have a players table:
CREATE TABLE players(
p_id INT NOT NULL PRIMARY KEY,
p_name VARCHAR(150) NOT NULL
)
I have a results table:
CREATE TABLE results(
f_id INT NOT NULL PRIMARY KEY,
f_datetime DATETIME NOT NULL,
p1_id INT NULL,
p2_id INT NULL,
FOREIGN KEY (p1_id) REFERENCES players(p_id) ON DELETE SET NULL ON UPDATE SET NULL,
FOREIGN KEY (p2_id) REFERENCES players(p_id) ON DELETE SET NULL ON UPDATE SET NULL
)
When I add an INSERT into the results table, I am adding the p1_id and p2_id. For this to work, I need to already have these id's defined in the players table, with the accompanying string name for this id. Programmatically, what should I do with my data before adding to the results table?
Check if p_id exists (from my p1_id and p2_id values), if not, INSERT them with the accompanying string.
Add my data into the results table as a normal insert
Or is there a more conventional way to do these things? Maybe some SQL quirk i'm not aware of?

making two columns primary key

Hello i have a table which has one primary key by the name of ImageID and i want to make another column
also primary key which is PropertyID means Composite Key
HERE IS THE CODE, but its showing this error for me "#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '( PropertyID INT, ImageID INT primary key (PropertyID, ImageID) )' at line "
Also the ImageID is already primary key, but with varchar(15) specification.
Alter TABLE properties (
PropertyID INT,
ImageID INT,
primary key (PropertyID, ImageID)
);
Each table can only have 1 primary key. You can only have one primary key, but you can have multiple columns in your primary key.
Taken from W3Schools:
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CONSTRAINT pk_PersonID PRIMARY KEY (P_Id,LastName)
)
Here the only primary key is pk_PersonID but that have stated that pk_PersonID is made up of P_Id and LastName.
Unique Indexes may be what you're looking for. This means unique values are required and runs like an index in that it can speed up queries.
Try this:
First drop the existing primary key
ALTER TABLE properties
DROP PRIMARY KEY;
Then add composite key
ALTER TABLE properties
ADD PRIMARY KEY(imageID, propertyID);
As I understand you already have a table with one key, which looks like the following:
CREATE TABLE `common`.`properties` (
`PropertyID` VARCHAR(15) NOT NULL,
`otherColumn` VARCHAR(45) NULL,
PRIMARY KEY (`PropertyID`));
And now you want to add another PK column and change the type of existing PK column from char to INT. So you need to do it as following:
ALTER TABLE `common`.`properties`
CHANGE COLUMN `PropertyID` `PropertyID` INT NOT NULL ,
ADD COLUMN `ImageID` INT NOT NULL AFTER `otherColumn`,
DROP PRIMARY KEY,
ADD PRIMARY KEY (`PropertyID`, `ImageID`);
P.S. common is my schema name, you can use your own, or even skip it if your schema is default.

Self relationship in MySQL

I am trying to add a self relation in an existing Innodb table here is table structure
Table person
person_id int (10) primary key not null auto increment,
parent_id int (10) NULL default null,
name varchar(30)
When I use this command
ALTER TABLE `person` ADD FOREIGN KEY ( `parent_id` ) REFERENCES `person` (`person_id`) ON DELETE RESTRICT ON UPDATE RESTRICT ;
I get the error data type mismatch. I think this could be due to null values in parent_id. Is there any way to skip this check?
Thanks
person_id and parent_id need to be the exact same data type. For example, if person_id is INT UNSIGNED and parent_id is INT, then you can't create the foreign key.
Run this command and compare the data types of the two columns:
SHOW CREATE TABLE `person`\G