Trying to create a Composite Primary Key in MSSQL with only a part of 2 columns - sql

I'm new to SQL and am following a course, however it does not cover the "create table" part.
It only covers statements etc.
What I would like to have is, my primary key (cust_id) to be generated with the "first_name" and the first 3 letters of "last_name".
I.E. I want "John Smith" to become "custid"; JOHNSMI.
I have below code which works (without composite).
CREATE TABLE NL_client (
custid INT PRIMARY KEY IDENTITY (10000, 1),
userid VARCHAR (50) NOT NULL,
first_name VARCHAR (50) NOT NULL,
last_name VARCHAR (50) NOT NULL,
birthday DATE
);
And I found below code (last line added)
CREATE TABLE SAMPLE_TABLE (
custid INT,
userid VARCHAR (50) NOT NULL,
first_name VARCHAR (50) NOT NULL,
last_name VARCHAR (50) NOT NULL,
PRIMARY KEY (first_name, last_name),
);
However, when trying to execte the second query as displayed above it does not create a Primary key. Or when I execure the below queries;
custid INT PRIMARY KEY (first_name, last_name),
Either above in the query or at the end, it does not make a primary key.
Furthermore, I have no idea, nor was I able to find (perhaps I searched wrongly, surely I'm not the first with this "problem") how to select only the first 3 letters of "last_name" to be used as a part of the "custid".
Perhaps this is not possible and I should use "custerid" as an INT Primary key and use "userid" as a composite.
But it would surely help me in the future to be able to use the Primary Key as a reference in Python.
Many thanks in advance for your help and let me learn to understand why it doesn't work!

Related

beginner sql missing keyword and invalid identifier

CREATE table Book
(
book_title varchar (100) not null ,
book_genre char(60) not null,
Date_of_publish date not null,
user_code char(7) not null ,
book_id char (7) primary key not null ,
constraint writer__id_fk foreign key (writer_id),
constraint publisher__id_fk foreign key (publisher_id)
);
I'm getting
[ORA-00905: missing keyword]
in publisher table
CREATE table publisher
(
publisher_id char (7) primary key not null,
publisher_name char(20) not null,
publisher_number char(10) not null,
publisher_email varchar2(60) not null,
publisher_address varchar2(60) not null,
);
I'm getting
[ORA-00904: : invalid identifier]
The following SQL creates a FOREIGN KEY on the "PersonID" column when the "Orders" table is created:
CREATE TABLE Orders (
OrderID int NOT NULL,
OrderNumber int NOT NULL,
PersonID int,
PRIMARY KEY (OrderID),
FOREIGN KEY (PersonID) REFERENCES Persons(PersonID)
);
Refer this link for more details
https://www.w3schools.com/sql/sql_foreignkey.asp
Hope this helps.
Welcome to the wonderful world of SQL! :-)
General remark:
Please tell us what kind of DBMS you're using. MySQL? SQL Server? Oracle? SQlite? Different systems use different kinds of syntaxes.
First statement:
The problem seems to be in the FOREIGN KEY-portion.
Usually, you'll state something like:
CONSTRAINT [constraint_name] FOREIGN KEY([column_in_this_table]) REFERENCES OTHER_TABLE([column_in_other_table])
edit (added):
The [column_in_this_table] has to exist in your DDL (CREATE TABLE-statement), like so:
CREATE TABLE Book ( book_title ... etc., publisher_id INT, CONSTRAINT FK_publ_id FOREIGN KEY(publisher_id) REFERENCES publisher(publisher_id));
Here, you'll have a 'original' column called 'publisher_id', in the 'publisher'-table. You refer to it from within the 'Book'-table, by first having a 'publisher_id' column in the 'Book'-table (which should have the same DDL as the original column by the way). Next, you'll add a FOREIGN KEY to the 'Book'-table, that is imposed on the Book(publisher_id) column. Note, that you could also name the column in your 'Book'-table differently -- like, say, 'Spongebob' or 'Patrick'. But for future use, you'd like naming conventions that tell what you might expect to find in a column. So you'd name columns for what they contain.
Second statement:
The problem is with the last portion of your statement, where there's a comma after the NOT NULL portion for column publisher_address.
(Part of) your statement:
publisher_address varchar2(60) not null, );
Try replacing that with:
publisher_address VARCHAR2(60) NOT NULL);
edit (note to self):
VARCHAR2 turns out to be a valid datatype in Oracle databases (see:
Oracle documentation)
For your first table, the Foreign Keys do not reference any table. For your second table, I would imagine that comma after your last column isn't helping anything.
So this is the answer.
CREATE table Book
(
book_title varchar (100) not null ,
book_genre char(60) not null,
Date_of_publish date not null,
user_code char(7) not null ,
publisher_id char (7) not null,
writer_id char(7) not null,
book_id char (7) primary key not null ,
CONSTRAINT book_writer_id_fk FOREIGN KEY(writer_id) REFERENCES writer(writer_id),
CONSTRAINT book_publisher_id_fk FOREIGN KEY(publisher_id) REFERENCES publisher(publisher_id)
);
CREATE table publisher
(
publisher_id char (7) primary key not null,
publisher_name char(20) not null,
publisher_number char(10) not null,
publisher_email varchar2(60) not null,
publisher_address varchar2(60) not null
);

create table in Oracle BD but gives error

CREATE TABLE employees (
id INT NOT NULL auto_increment PRIMARY KEY (ID),
first_name VARCHAR(20) DEFAULT NULL,
last_name VARCHAR(20) DEFAULT NULL,
salary INT DEFAULT NULL);
I think this is correct query to create table in Oracle database.. but it gives the following error:
ORA-00907: missing right parenthesis
How to correct the statement?
You can validate your SQL using formatting tools such as http://www.dpriver.com/pp/sqlformat.htm
auto_increment seems like a proprietary MySQL extension, so it's not valid for Oracle.
also, "id int not null auto_increment primary key (id)" does not need the last "(id)"
Using Oracle, you shoud try something like this
CREATE SEQUENCE seq;
CREATE TABLE employees
(
id INTEGER NOT NULL PRIMARY KEY,
first_name VARCHAR2(20) DEFAULT NULL,
last_name VARCHAR2(20) DEFAULT NULL,
salary INTEGER DEFAULT NULL
);
INSERT INTO employees
VALUES (seq.NEXTVAL,
'name',
'last name',
1);
Sometimes, SQL is fancy, because even having a standard (ANSI), most DBMS vendors add their proprietary extensions to the SQL creating their own languages, so it's rare the situation where you can port one SQL from one DB into another without any changes.
Also, it's a pretty useless error message. It could at least say which position. (also, there's no missing parenthesis, but an unexpected token)
EDITED : New feature 12c
CREATE TABLE employees(
id NUMBER GENERATED ALWAYS AS IDENTITY,
first_name VARCHAR2(30)
etc.
);
Why would you do default null?
The VARCHAR datatype is synonymous with the VARCHAR2 datatype. To avoid possible changes in behavior, always use the VARCHAR2 datatype to store variable-length character strings.
Replace
id INT NOT NULL auto_increment PRIMARY KEY (ID),
with
id INT NOT NULL auto_increment PRIMARY KEY,
this is more efficient
CREATE TABLE EMPLOYEES_T(
ID NUMBER,
FIRST_NAME VARCHAR2(20) DEFAULT NULL,
LAST_NAME VARCHAR2(20) DEFAULT NULL,
SALARY INTEGER DEFAULT NULL,
CONSTRAINT PK_EMPLOYEES_T PRIMARY KEY(ID)
);

sql 3NF Normalization

is this in 3NF ?
create table movies(
id numeric primary key not null default autoincrement,
name varchar(50) not null,
release-date Date,
price numeric,
rating numeric,
length numeric,
description varchar(1500)
);
create table movies(
id numeric primary key,
name varchar(20)
);
create table genre(
name varchar(20) primary key
);
create table directors(
id numeric primary key not null default autoincrement,
first-name varchar(32) not null,
last-name varchar(32) not null,
gender varchar(8),
dob Date,
biography varchar(1000)
);
create table movie-Star(
id numeric primary key not null default autoincrement,
first-name varchar(20) not null,
last-name varchar(20) not null,
gender varchar(8),
dob Date,
hometown varchar(20)
);
create table movies-cast(
movie-id numeric references movies(id),
actor-id numeric references movie-Star(id),
role varchar(32),
primary key (movie-id, actor-id)
);
Create table Studio(
studio-id numeric references directors(id)
Directer-name varchar(20) not null
name varchar(20) primary key
);
create table directors(
id numeric primary key not null default autoincrement,
first-name varchar(32) not null,
last-name varchar(32) not null,
gender varchar(8),
dob Date,
biography varchar(1000)
);
It looks pretty well structured. I don't see any normalization problems. However:
Movies and Directors tables are created twice.
Genre table is not used for anything (presumably should be in movies).
Same with Studios.
Current arrangement allows only one director per studio. This should probably be A) one studio per director (add studio_id column to directors) or more likely B) many-to-many relationship between studio and director (add new studio_directors table).
Current arrangement does not associate Director with Movie.
You might consider combining Director and Movie-Start into one table called Talent. You have data duplication in which a star is also a director. This is the biggest normalization issue with your design.
if all can not be duplicated again then it is included 3NF.
make sure there are not duplicate data again
It has e PK, so it's in 1NF. It's PK is not composite, so it's in 2NF. All the columns are dependent on nothing but the key, so it's in 3NF. There no keys other than PK, so it's in BCNF.

Is there any ISO standard of how to write SQL queries in DDL?

I am doing my first database project.
I would like to know which of the following ways should I use to make SQL queries in DDL.
#1
CREATE TABLE employees (
id INTEGER PRIMARY KEY,
first_name CHAR(50) NULL,
last_name CHAR(75) NOT NULL,
dateofbirth DATE NULL
);
#2
CREATE TABLE employees (
id INTEGER PRIMARY KEY,
first_name CHAR(50) NULL,
last_name CHAR(75) NOT NULL,
dateofbirth DATE NULL
);
#3
CREATE TABLE employees (
ID integer PRIMARY KEY,
FIRST_NAME char(50) NULL,
LAST_NAME char(75) NOT NULL,
DATAOFBIRTH data NULL
);
It doesn't really matter to the database, and so you should generally go for what's more readable and maintainable. There are a lot of different conventions out there, and I switch between them depending on circumstances all the time. Imo, what's good for a small query isn't the same as what's good for a more-complicated query.
In this case, I think your #3 looks most readable. But that's just my opinion and if there are conventions or existing expectations for how the code looks where you are, stick to that.
Sql coding Convections suggest :
CREATE TABLE employees
(
id INTEGER PRIMARY KEY,
first_name CHAR(50) NULL,
last_name CHAR(75) NOT NULL,
dateofbirth DATE NULL
);

Wildcard character in CHECK in Create table taken as string

I created an info table that stores employee record, the SQL query for it as follows...
CREATE TABLE info1 (
empid VARCHAR(8) PRIMARY KEY CONSTRAINT empchk
CHECK (empid IN ('kh\%' ESCAPE '\''),
initials CHAR(6), fname CHAR(25) NOT NULL,
lname CHAR(25),
userstatus INTEGER NOT NULL,
designation CHAR(10) NOT NULL
);
Now, as you can see constraint in empid is kh% where - as far as I remember - % means that any number of the following characters (limited to 8 of course) can be anything, right?
I am using Java DB and strangely it has taken the % symbol also to be a part of the string so if I enter khce0001, it says empchk violation, it only takes in kh%
What should I do? Why is this happening?
The mistake in this SQL query is that I have used IN instead of LIKE (which I believe does wildcard checking), so
I dropped the constraint with...
ALTER TABLE info DROP CONSTRAINT empchk;
and altered the table with...
ALTER TABLE info ADD CONSTRAINT empchk CHECK (empid LIKE ('kh%'));
and hence the correct SQL Query should have been...
CREATE TABLE info1 (
empid VARCHAR(8) PRIMARY KEY CONSTRAINT empchk
CHECK (empid LIKE ('kh%')),
initials CHAR(6),
fname CHAR(25) NOT NULL,
lname CHAR(25),
userstatus INTEGER NOT NULL,
designation CHAR(20) NOT NULL
);