SQL Server 2008 - Create a table - sql-server-2008

My table is:
CREATE TABLE Employee
(
EID INT PRIMARY KEY NOT NULL,
Efname VARCHAR(60) NOT NULL,
Elname VARCHAR(60) NOT NULL,
Efathername VARCHAR(60) NOT NULL,
Ephone VARCHAR(25) NOT NULL,
Eaddress VARCHAR(1000),
Erecruitment_date DATE NOT NULL,
Epension VARCHAR(25),
Ecomment VARCHAR(5000) DEFAULT'',
CONSTRAINT CXX_Epension CHECK(Epension NOT LIKE'%[^0-9]%'),
CONSTRAINT CXX_Ephone CHECK(Ephone NOT LIKE'%[^0-9]%'),
CONSTRAINT CXX_Efname CHECK(Efname NOT LIKE'%[^ a-zA-zا-ی]%'),
CONSTRAINT CXX_Elname CHECK(Elname NOT LIKE'%[^ a-zA-zا-ی]%'),
CONSTRAINT CXx_Efathername CHECK(Efathername NOT LIKE'%[^ a-zA-zا-ی]%'),
)
I want EID to be 10 characters long, and the first 6 characters are year and month of Erecruitment_date (example: 2001 02). The next 4 should be the first four characters of Ephone (example: 0098)

If I understand correctly, your requirement is this:
First 6 digits of EID should be the year and month parts of Erecruitment_date e.g. '200501' for date '20050101'.
Next 4 digits of EID should be the first 4 digits of Ephone e.g. '1234' for phone number '12345678'
The constraint can then be written as:
CONSTRAINT CXX_Test CHECK
(substring(cast(eid as varchar),1,4)=cast(year(erecruitment_date) as varchar)
AND substring(cast(eid as varchar),5,2) = right('00' + cast(month(erecruitment_date) as varchar),2)
AND substring(cast(eid as varchar),7,4) = substring(ephone,1,4)
)
Note that you are storing EID as an int, so you need to ensure that the value coming in from your application is a 10-digit number to begin with. Otherwise, 1, 01, 001 and 000001 are all the same as far as int is concerned.

Use substring() to select the particular year,date and phone number.
Use concat() to concatenate them and assign to EID.
Reference :
SUBSTRING
CONCAT
But logically, this may not always produce a unique ID. Consider, x and y got recruited on the same day and same year. And say their phone numbers has the same first four digits. They will have same EID.

Related

How can I limit INT in MySQL? [duplicate]

This question already has an answer here:
SQL Integer Range When Creating Tables
(1 answer)
Closed 1 year ago.
I'm creating a college grading system with Java. I have a credit number column in courses table. I want this credit number to be limited between 1 to 8. I don't want any other number to be entered. I'm a beginner.
CREATE TABLE courses(
id INT PRIMARY KEY,
course_name VARCHAR(50) NOT NULL,
credit_number BETWEEN 1 AND 8 NOT NULL,
course_description VARCHAR(255));
Use a check constraint:
CREATE TABLE courses (
id INT PRIMARY KEY,
course_name VARCHAR(50) NOT NULL,
credit_number int NOT NULL,
course_description VARCHAR(255),
CONSTRAINT chk_courses_credit_number CHECK (credit_number BETWEEN 1 AND 8)
);
Slight variation on the accepted answer -
You could also use TINYINT instead of INT, which would restrict the possible range to -128 to 127 (one byte), which is okay since you only need 1-8:
https://dev.mysql.com/doc/refman/5.7/en/integer-types.html
CREATE TABLE courses (
id INT PRIMARY KEY,
course_name VARCHAR(50) NOT NULL,
credit_number TINYINT NOT NULL,
course_description VARCHAR(255),
CONSTRAINT chk_courses_credit_number CHECK (credit_number BETWEEN 1 AND 8)
);

How to add a number to a time before ordering (MySQL)

Running a very basic database including details on customers, car parks and parking sessions, I would like to return all parking sessions ordered by the end time in ascending order for a particular car.
However i only have the beginning time and length(in hours, stored as an int) of each session.
Below is my best attempt however this only orders by the start time.
(TimeDateStart in this case is the start time and date of the parking session stored as datetime datatype)
It is the order by part I cannot figure out, the rest works as desired and returns the parking sessions for this car.
SELECT *
FROM ParkingSession
JOIN Customer ON ParkingSession.CustID = Customer.CustID
WHERE Customer.Registration = "BH34 JHN"
ORDER BY (TIME(DateTimeStart) + Hours) ASC;
The Tables this is being run on is as follows (I dont think the customer table is needed but i thought i would include it anyway):
CREATE TABLE Customer (
CustID INT AUTO_INCREMENT PRIMARY KEY,
FName VARCHAR(30) NOT NULL,
LName VARCHAR(30) NOT NULL,
Registration CHAR(8) NOT NULL,
CreditCard BLOB NOT NULL,
CVC BLOB NOT NULL,
Email VARCHAR(45) NOT NULL);
CREATE TABLE ParkingSession (
CarParkID INT,
CustID INT,
DateTimeStart DATETIME,
Hours TINYINT,
PRIMARY KEY(CarParkID,CustID,DateTimeStart),
CONSTRAINT FK_Carpark FOREIGN KEY (CarParkID) REFERENCES CarPark(CarParkID),
CONSTRAINT FK_Customer FOREIGN KEY (CustID) REFERENCES Customer(CustID));
You want to add an interval of some hours to a datetime. That's
ORDER BY DateTimeStart + INTERVAL Hours HOUR

how to avoid blank space while using char field in sql

I have two tables one is a customer table and the second is sales table.
I need to create a query to display customer name, customer_id and number of Gadgets bought (write two queries using different syntaxes of JOIN). Example : “John Barry - 111 bought 5 gadgets”.
CUSTOMERS_JS
create table CUSTOMERS_JS (
CUSTID smallint not null,
CUSTNAME char(50) not null,
primary key(CUSTID)
);
STORE_SALES_JS
create table STORE_SALES_JS (
SALEID smallint not null,
SALETS datetime not null,
GADGETID smallint not null,
EMPID smallint not null,
CUSTID smallint not null,
primary key(SALEID),
foreign key(GADGETID) references ELEC_items_JS(GADGETID),
foreign key(EMPID) references Store_EMPS_JS(EMPID),
foreign key(CUSTID) references CUSTOMERS_JS(CUSTID)
);
I did this query
select concat(CUSTNAME,' - ',STORE_SALES_JS.CUSTID,' bought ',count(STORE_SALES_JS.GADGETID),' gadgets') as result
from CUSTOMERS_JS,STORE_SALES_JS
where STORE_SALES_JS.CUSTID = CUSTOMERS_JS.CUSTID
group by STORE_SALES_JS.CUSTID,CUSTNAME
order by STORE_SALES_JS.CUSTID
but there is too much space between the name and the '-'. I tried to change the name field to varchar and it worked as it supposed to work but I need it to work with char(50) as well.
Thanks to scaisEdge help I managed to fix this issue while using rtrim function
select concat(rtrim(CUSTNAME),' - ',STORE_SALES_JS.CUSTID,' bought ',count(STORE_SALES_JS.GADGETID),' gadgets') as result
from CUSTOMERS_JS,STORE_SALES_JS
where STORE_SALES_JS.CUSTID = CUSTOMERS_JS.CUSTID
group by STORE_SALES_JS.CUSTID,CUSTNAME
order by STORE_SALES_JS.CUSTID
if you must use char and not varchar but need a trimmed result in your select you could trim ( or rtrim or ltrim) your custname for remove the spaces
select concat(rtrim(CUSTNAME),' - '
,STORE_SALES_JS.CUSTID,' bought '
,count(STORE_SALES_JS.GADGETID),' gadgets') as result
from CUSTOMERS_JS,STORE_SALES_JS
where STORE_SALES_JS.CUSTID = CUSTOMERS_JS.CUSTID
group by STORE_SALES_JS.CUSTID,CUSTNAME
order by STORE_SALES_JS.CUSTID

Better Database design for hibernatre?

I am new to database design. I am using MySQL
I have a Form table which contains a field Country
Since the values in this columns can be one from the country list only, so I made this column int instead of varchar and put the list in a new table. shown as below:
Instead of having country column like
country varchar(255) NOT NULL
I made it countryCode with datatype INT and added a Foreign Key to table CountryMaster which is shown as below
...
countryCode INT NOT NULL,
FOREIGN KEY (countryCode) REFERENCES CountryMaster (countryCode),
...
create table CountryMaster(
countryCode INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255)
);
It is working fine, but the issue is that the same table contains many more column like formStatus (with possible values Draft, Saved, Approved), gender (Male, Female), bloodGroup (A, B, O), rHFactor (+ve, -ve), occupation (Service, Business, Student, Unemployed) etc. If I will make separate table for each such column I will end up in 20 to 25 Master tables.
I also tried to put all such Master Date in a single table i.e. CommonMaster with columns type, key and value shown as below:
create table CommonMaster(
commonCode INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
type VARCHAR(255) NOT NULL,
key INT NOT NULL,
value VARCHAR(255) NOT NULL
);
with values like:
code type key value
7 BLOOD_GROUP 1 A
8 BLOOD_GROUP 2 B
9 BLOOD_GROUP 3 O
10 RH_FACTOR 1 +ve
11 RH_FACTOR 2 -ve
12 OCCUPATION 1 Service
13 OCCUPATION 2 Profession
14 OCCUPATION 3 Business
15 OCCUPATION 4 Student
16 OCCUPATION 5 Unemployeed
I want to know that what is a better approach and why. I also have to use hibernate orm in the project. So the design should be pertaining to that.
I prefer a hundreds master tables than a common table with all the types; more structure, more organization, more adaptive for add, delete and update the value of then, also for reports.

MySQL auto increment plus alphanumerics in one column

I am new to MySQL coming from Oracle. I have a requirement to create a table with the primary key in one column but with the following format.
X-A letter stating the country of origin e.g. S for Spain, Z for Zimbabwe e.tc (we have five countries of origins only)
YYYYMMDD - Date in that format,
9999 - 4 digit office code.
9999999 - 7 right padded sequence number from a sequence in Oracle (auto increment in MySQL)
This gives me a primary key like Z2010013150110000001 as the primary key.
My question is how do I generate the part of 9999999 in MySQL. In Oracle it would have been
select 'Z'||to_char(sysdate, 'YYYYMMDD')|| 5011||cust_id.nextval from dual;
auto_increment can't be just part of a field, so a single column might be a wash. So how about:
CREATE TABLE xxxxx (
id int unsigned not null auto_increment,
rest_of_that_key char(xx) not null,
// other goodies
PRIMARY KEY (id)
);
Then you can SELECT CONCAT(rest_of_that_key, LPAD(id, 7, '0')) AS full_key FROM xxxxx.
Or even better, so you can use those office codes and dates to filter data with:
CREATE TABLE xxxxx (
id int unsigned not null auto_increment,
country_code char(1) not null,
sysdate date not null,
office_code smallint unsigned not null,
// other goodies
PRIMARY KEY (id),
KEY country_code (country_code)
// etc, index the useful stuff
);
Then you can use SELECT CONCAT(country_code, DATE_FORMAT(sysdate, '%Y%m%d'), office_code, LPAD(id, 7, '0')) AS full_key FROM xxxxx and even throw in a WHERE office_code = 1256 AND sysdate >= '2010-01-01' without having to somehow parse that huge string.
If you really need that huge string as a single-field primary key, you'll have manually increment things yourself. I still wouldn't recommend doing it though, MySQL really likes its PKs to be numeric.