Query that combines 3 tables - postgresql

I need to display the names of projects on which employees from the department called "Programmers" work. I am stuck on this query, can someone help me?-
I got three tables.
departments where department id of 3 is Programmers
department_id
name
projects:
p_id
p_name
employees
id,
name,
department_id
SELECT p_name from PROJECTS
WHERE...

Given the three tables you provided I do not think you can do it. There is nothing linking projects to either employees or departments. You will need another table (employeesOnProject or deparmentprojects, etc) to do it.

Related

How would I associate users with different company tables?

In the below diagram you can see I have profiles for users. A user means the profile is associated with a login. If they don't have a login account they are merely a "contact" at the company tables you see on the right.
I am creating a CRM that needs to be able to store many facilities, customers, vendors, etc.
My question is how would I associate that profile with the company it belongs too? If I went to there profile page, for example, I should see what company they work for, regardless of what table the company is in.
I have 2 ideas but both seem flawed. One is to make a separate profile table for contacts for each. Example. vendor_profiles, customer_profiles, etc. This seems messy.
My other idea was to make a vendor_id, customer_id, etc column in the profile table, set them all to NULL by default, and if they belong to a vendor then my application code would check each for a number, and I think you get where I am going from there. Again, seems very messy, and inefficient.
I also considered grouping the Vendors, Customers, so on into one table and just setting a "type" but they all store very different info and are used in different, and often, relational ways.
Introduce a new organization table which unifies those aspects of vendor, customer,
facility and our_company that they all share in common:
CREATE TABLE organization (
organization_id serial4
type text);
CREATE TABLE profile (
profile_id serial4
user_id int4 REFERENCES user
organization_id int4 REFERENCES organization
...);
Then add an organization_id foreign key to vendor, customer, facility and our_company
so these tables can be joined to organization when the extra info in those tables are needed.
CREATE TABLE vendor (
vendor_id serial4
organization_id int4 REFERENCES organization
vendor_specific_field text
...);
Note that if you use "unique" names for id fields (such as organization_id instead of id) which have a consistent meaning across all tables, then you can JOIN ... USING syntax
SELECT *
FROM profile p
INNER JOIN organization o USING (organization_id)
INNER JOIN vendor v USING (organization_id)
WHERE o.type = 'vendor'
instead of
SELECT *
FROM profile p
INNER JOIN organization o ON p.organization_id = o.id
INNER JOIN vendor v ON v.organization_id = o.id
WHERE o.type = 'vendor'
which may improve readability and reduce potential errors in join conditions. (You'll never have to wonder what field in one table connects to the id field in another table.)

Is there a database can represent set-like structure?

I mainly focus on the query operation, not union or intersection.
Here is an example.
Let say we have a multi-level category:
CATEGORY-TOP-LEVEL:
CATEGORY1:
CATEGORY1.1:
item1
CATEGORY2:
CATEGORY2.1:
item2
Here, item[N] is the data. Category is a tree structure to represent which category the item belongs to.
Now, suppose I'd like to query all data in category 1, the database should give me item1.
Suppose I'd like to query all data in category-top-level, the database should give me item1 and item2.
It's like set theory. Because item1 belongs to CATEGORY1.1, and CATEGORY1.1 belongs to CATEGORY1. Thus item1 belongs to CATEGORY1.
One solution is use Materialized Paths: We put an field in item, named path, the value is like: ",CATEGORY-TOP-LEVEL,CATEGORY1,CATEGORY1.2". But the problem is it will cause a lot of writing operations when I change a category's name or the hierarchy of the category.
Can MongoDB support that? if not, is there a database can support that?
P.S. Let's take query performance into consideration.
Every modern relational database can support that.
There are different ways of modeling this in a relational database, the most common one is called the "adjacency model":
create table category
(
id integer primary key,
name varchar(100) not null,
parent_category_id integer references category
);
If an item can only ever belong to a single category, the item table would look like this:
create table item
(
id integer primary key,
name varchar(100) not null,
category_id integer not null rerences category
);
If an item can belong to more then one category, you need a many-to-many relationship (also very common in the relational world)
To get all categories below a certain category you can use a recursive query:
with recursive cat_tree as (
select id, name, parent_category_id
from category
where id = 42 -- this is the category where you want to start
union all
select c.id, c.name, c.parent_category_id
from category c
join cat_tree p on p.id = c.parent_category_id
)
select *
from cat_tree;
To get the items together with the categories, just join the above to the item table.
The above query is standard ANSI SQL.
Other popular models are the nested set model, the materialized path (you mentioned that) and the closure table.
This gets asked a lot. See the tags recursive-query and hierarchical-data for many more examples.

select from normalized tables using external references

I am trying to create a normalized set of tables for my books and then
to select them ordering by either book title or authors.
I want to be able to have 'n' books per author, and 'n' authors per book.
The problem I want to solve is how to display my books and authors
ordered by tile or by lastname,firstname,middlename?
I started with a table like this with some 1441 entries.
create table books(
bookid serial,
title text,
firstname text,
lastname text);
I then created an authors table
create table authors(
authorid serial,
firstname text,
lastname text);
and populated it.
I then created a cross reference table
create table bookAuthor
(
bookId INTEGER NOT NULL REFERENCES books(bookId),
authorId INTEGER NOT NULL REFERENCES authors(authorId)
);
and
create unique index bookAuthor_unique_index on bookAuthor(bookId, authorId);
I then populated the bookauthor table with 1441 entries.
I am pretty sure the three tables are populated correctly. I managed to
do several inserts into the authors table and then insert the correct cross relationshipes into the bookauthor table.
I am now stuck, I can't figure out how to display my books and authors
ordered by title or by authors names.
Am I going down the wrong path to create this ability to create N titles per author and N authors per book.
I did multiple searches for foreign keys, and multiple tables with nothing that seemed to resolve my problem.
I'm in a postgresql 9.x environment.
A join will be helpful.
select * from bookAuthor
inner join books on bookAuthor.bookId = books.bookid
inner join authors on bookAuthor.authorId = authors.authorid
order by books.title;
Or you can order by authors.lastname, authors.firstname instead.

Foreign key from multiple tables

I am thinking of three tables;
Employee with emp_id an, emp_name and other related data.
and
Person table with person_id, person_name and other related data.
and
GroupList with grp_list_id, member_id (either emp_id or person_id) and is_employee (true for employee and false for person) and other related data.
This is the first time I am trying to do a table whose foreign key can come from two different tables. Can someone please suggest the best way to achieve it?

T-SQL, Get distinct values from column in source, check target, insert if not exist

I've seen several somewhat similar questions, but nothing exactly like mine. A T-SQL god should be able to answer this is a flash.
Source table (feeder) of employees and department codes from HRMS system feed. I have an employees table and a departments table in my SQL Server database. I need to have a stored proc that will first get a distinct list of department codes in the feeder table, then check those codes to see if they exist in the departments table. If they don't then insert into the departments table from the feeder table. Then, do the insert into the employee table.
Right now I have found that one of the business analysts has been getting separate list of departments in Excel and adding them manually. Seems crazy when the data is already coming into the feeder table from HRMS. I can do the inserts, but I don't know how to loop through feeder table to see if the department code in each row exists in the departments table already. Thanks for any assistance.
J.
You can use the merge keyword in SQL 2008 or greater. I just tested this snippet:
merge department as d
using feeder as f on f.code = d.code
when not matched then
insert (code)
values (f.code);
Merge will work. Since we're just doing inserts though, this will too:
INSERT
department
(
departmentCode
)
SELECT departmentcode
FROM
(
SELECT
departmentcode
FROM
feeder
EXCEPT
SELECT
departmentcode
FROM
department
) c;
With indexes on departmentcode in both tables, this pattern usually performs well.