Indicate that a table's attribute is derived in SQL - sql

Is there a way in SQL to specify that an attribute is derived? Currently, I'm creating a table Employee, which has a derived attribute age, but I've no idea how to indicate it (and I'm afraid there's no way to do it):
create table Employee(
Id int NOT NULL UNIQUE PRIMARY KEY AUTO_INCREMENT,
Age int, # How to indicate this is a derived attribute?
Country varchar(255),
City varchar(255),
Birthrate double,
);

If what You mean is that age is derived from birthrate, I think You should consider if You really need age column in Your table at all. If You are not creating data warehouse here, calculating age each time will be much saner than maintaining this column in production... Think of it - this column should be recalculated everytime someone have a birthday!
For convenience, You can always create view for it, like this:
CREATE VIEW Employee_view AS
SELECT
e.Id,
=>here some database specyfic calculation to calculate age<= as Age,
e.Country,
e.City,
e.Birthrate
FROM Employee e;

Related

How to insert salary "NULL" in sql

How do I implement a sql command which outputs NULL for salary if it is a voluntary worker?
Here are the tables I created first:
create Table worker (
pid integer references Person,
salary float);
create Table person(
pid integer primary key,
name varchar(30),
adress varchar(30));
Since I'm not sure how to distinguish a normal worker from a voluntary one, I decided to make another table. Unfortunately, I don't know how to insert NULL values for salary for all voluntary workers. That is what I tried out:
create table voluntaryworker(
pid integer references Person,
salary = null);
insert into Person (pid, name, adress) values (1345, anna, 'festreet');
insert into voluntaryworker (pid, salary) values (1345, null);
pid = person ID
Most databases support generated columns. If you really want a salary column in voluntaryworker, then you can use such a column:
create table voluntaryworker (
pid integer references Person,
salary generated always as (cast(null as float))
);
The exact syntax may vary, depending on the database.
Note that having a separate table seems utterly superfluous. Why not just have a flag in the worker table.
Also, representing the salary as a float is quite troublesome. In general, you really should never use floating point representations for monetary amounts. decimal/numeric is much more appropriate for money.
Like others commented, you certainly don't need another table to implement this. All you need is some way to remember whether a worker is voluntary.
To make sure salary sticks to your rule, you can add a CHECK constraint:
CREATE TABLE worker (
pid integer PRIMARY KEY REFERENCES person
, voluntary boolean NOT NULL DEFAULT false
, salary numeric
, CONSTRAINT voluntary_has_no_salary CHECK (NOT voluntary OR salary IS NULL)
);
Meaning: voluntary workers cannot have a nonnull salary.
Alternatively, you might drop the table worker, too, and just add the columns worker_salary and worker_voluntary to table person. (You may need an additional flag worker, or integrate this information in the other two columns ...)
If you are still interested in generated columns (not needed here), see this example with correct syntax and instructions:
Computed / calculated / virtual / derived columns in PostgreSQL
Related:
PostgreSQL: Which Datatype should be used for Currency?
At least insert into voluntaryworker (pid) values (1354); leaves it NULL.

How do I realize this 3 simple things in SQL?

i am an absolute SQL beginner and i already did search a lot with google but didnt find what i needed. So how do i realize in SQL(translated from a ER-Model):
An Entity having an Atribute that can have mulitple Entrys(I already found the ARRAY contstraint but i am unsure about that)
An Entity having an Atribute that consists itself of a few more Atributes(Picture: http://static3.creately.com/blog/wp-content/uploads/2012/03/Attributes-ER-Diagrams.jpeg)
Something like a isA Relation. And especially the total/partial and the disjunct characteristics.
Thanks already
In Postgres you have all three of this:
create table one
(
id integer primary key,
tags text[] -- can store multiple tags in a single column
);
A single column with multiple attributes can be done through a record type:
create type address as (number integer, street varchar(100), city varchar(100));
create table customer
(
id integer primary key,
name varchar(100) not null,
billing_address address
);
An isA relation can be done using inheritance
create table paying_customer
(
paid_at timestamp not null,
paid_amount decimal(14,2) not null
)
inherits (customer);
A paying customer has all attributes of a customer plus the time when the invoice was paid.

Multi valued column in SQL

I created a table for Boat that contains the following columns: BName, Type, Price, OName.
However, the Type column should be one of the following: Sailboat, Houseboat, or Deckboat.
How can I reflect this on the create table statement. I've searched about it and I came up with this statement which I'm not sure if it's right or not:
CREATE TABLE Boat
(
BName varchar(255),
BType int,
Price double,
OName varchar(255),
PRIMARY KEY (BName),
FOREIGN KEY (BType) REFERENCES BoType(ID)
);
CREATE TABLE BoType
(
ID int PRIMARY KEY,
Type varchar(255)
)
Is this the best way to do it?
You can try something like this:
mycol VARCHAR(10) NOT NULL CHECK (mycol IN('moe', 'curley', 'larry'))
Here are more details on MSSQL "Check Constraints":
http://technet.microsoft.com/en-us/library/ms188258%28v=sql.105%29.aspx
That's the best way to do it just make sure that you populate the BoType table with the desired reference values (i.e. Sailboat, Houseboat, Deckboat). Because if you use constraint then you have the user of the database who have no knowledge in SQL or have no access rights in your DB, at your mercy or they become too dependent on you. However, if you set it as a separate table then the user of your system/database even without knowledge about SQL could add or change values via your front-end program (e.g. ASP, PHP). In other words you design is more flexible and scalable not to mention less maintenance in your part.

SQL gym with less workers per district

I'm struggling to find how to make a specific query to a set of tables that I have on my local database.
CREATE TABLE Gym (
eid INT PRIMARY KEY,
name VARCHAR(127) UNIQUE,
district VARCHAR(127),
area INT);
CREATE TABLE Trainer (
id INT PRIMARY KEY,
name VARCHAR(127),
birth_year INT,
year_credentials_expiry INT
);
CREATE TABLE Works (
eid INT,
id INT,
since INT,
FOREIGN KEY (eid) REFERENCES Gym (eid),
FOREIGN KEY (id) REFERENCES Trainer (id),
PRIMARY KEY (eid,id));
The question is the following: I have several gyms and there are some cases where two or more gyms are located on the same district. How can I know, by district, which is the gym with less trainers on it?
The only thing I managed to get is the number of trainers per gym. Considering that, I can only get the gym with the minimum trainers from all districts...
NOTE: I am NOT allowed to use subqueries (SELECT inside SELECT's; SELECT inside FROM's)
Thank you in advance.
If you can have subqueries in the where or having clauseclause, then you can approach it this way.
First look at your query that counts the number of trainers by district.
Now, write a query (using that as a subquery) that calculates the minimum number of trainers in a gym in a district.
Next, take your first query, add a having clause and correlate it to the second by district and number of trainers.
This does use a subquery in a subquery, but it is in the having clause. I'm not writing the query for you, since you need to learn how to do that yourself.
By the way, if you have window/analytic functions there may be other solutions.

SQL Server / ADO.Net: entity with multi-part FK primary key, with one part optional?

Here's an SQL Server / ADO.Net Entity Framework question: I'm looking for the "best" way to do this.
I have a hierarchical structure of objects similar to the following:
Company -> Division -> Department -> Group -> Specialty
The primary key of each (other than Company) consists of a foreign key pointing to the PK of each of its ancestors. So, Specialty looks like this:
[PK/FK] CompanyID (string)
[PK/FK] DivisionID (int)
[PK/FK] DepartmentID (int)
[PK/FK] GroupID (int)
[PK] SpecialtyID (int)
Name (string)
Description (string)
This basic structure has to remain in place for reasons I won't go into - so using a GUID as the PK really isn't in the cards -- we have to interface with other apps that rely on the "Bergdorf.6.3.4.1" ID construct that this structure reflects.
What I need to do now, though, is add the ability to add a Specialty which applies to an entire Department, rather than to a group. So, in an ideal world, we'd have this:
[PK/FK] CompanyID (string)
[PK/FK] DivisionID (int)
[PK/FK] DepartmentID (int)
[PK/FK] GroupID (int/NULL)
[PK] SpecialtyID (int)
Name (string)
Description (string)
...such that if the Specialty's GroupID is null, that means it applies to the whole department.
But, of course, you can't have a nullable field as part of a PK. So that's a no-go.
It also won't work to just pull GroupID out of the PK, because then SpecialtyID is going to have to be unique across an entire Department, and we already have established IDs that make that impossible.
Can't make a "special" GroupID (e.g. "-1") that means "No Group", because the FK constraints would require us to create a Group with an ID of -1 for every single Department.
...So... what's the right thing to do here? Do I have to make a GUID for Specialty, and pull all those FKs out of the PK? Would really like to avoid that if possible.
Any ideas would be much appreciated!
I recommend you have two (subtype) base tables with no nullable columns: one for Department Specialties and another for Group Specialties. You'll probably want a third (supertype) table for all specialities so that you can have SpecialtyID values that are unique to all Specialties regardless of subtype.
Then you coould have a VIEW that UNIONs the subtypes together and here you can introduce a default value (e.g. -1) for the 'missing' GroupIDs for Department Specialities. You could go further and only expose the VIEW, don't expose the base tables and use INSTEAD OF triggers on the VIEW to hande updates to the base table.
You would anyhow need a mechanism to ensure that for every Specialty (supertype) created exactly one Department Specialty or Group Specialty is also created e.g. you could revoke all write permissions on all realted base tables and VIEWs and force users to create Specialties uses CRUD procedures you've coded to ensure the super/subtype requirements are always satisfied.
You could create a "null-buster" computed column, based on the nullable GroupID column, and make it part of the PK instead of GroupID:
create table Specialities (
CompanyID varchar(10) not null,
DivisionID int not null,
DepartmentID int not null,
GroupID int null,
SpecialityID int not null,
Name varchar(10) not null,
Description varchar(max) not null,
_NNGroupID as ISNULL(GroupID,-1),
constraint PK_Specialities PRIMARY KEY (CompanyID,DivisionID,DepartmentID,_NNGroupID,SpecialityID)
)
I'm not sure whether I like this idea or not, but it may be an option for you. This assumes that no real GroupID of -1 will ever exist - you may have to pick a different magic value for your purposes. So long as the value on the right-hand side of the ISNULL is not part of the domain of real GroupIDs, this should work.
You continue to have the foreign key defined against GroupID rather than _NNGroupID so that the nullable-ness of the foreign key constraint works as you expect.
You could create an xref table linking Specialty with Department: xSpecialtyDepartment(SpecialtyID int, DepartmentID int)