SNpn
SNpn

Reputation: 2207

Postgresql finding and counting unique tuples

I have a question where I must find unique tuples in a table, where they have not ever been seen inside another table. I then must count those tuples and display the ones that occur more then 10 times. That is, there are some jobs that don't require job staff, I am to find the jobs that have never ever required a job staff and has ran in terms more then 10 times.

create table JobStaff (
    Job         integer references Job(id),
    staff       integer references Staff(id),
    role        integer references JobRole(id),
    primary key (job,staff,role)
);

create table Job (
    id          integer, 
    branch      integer not null references Branches(id),
    term        integer not null references Terms(id),
    primary key (id)
);

Essentially my code exists as:

CREATE OR REPLACE VIEW example AS
SELECT * FROM Job
WHERE id NOT IN (SELECT DISTINCT jobid FROM JobStaff);

create or replace view exampleTwo as
select branch, count(*) as ct from example group by 1;

create or replace view sixThree as
select branch, ct from exampleTwo where ct > 30;

This seems to return two extra rows then the expected result. I asked my lecturer and he said that it's because I'm counting courses that SOMETIMES

EDIT: this means, that for all the terms the job was available, there were no job staff assigned to it

EDIT2: expected output and what I get:

what i got:

 branch  | cou
---------+-----
    7973 |  34
    7978 |  31
    8386 |  33
    8387 |  32
    8446 |  32
    8447 |  32
    8448 |  31
   61397 |  31
   62438 |  32
   63689 |  31

expected:

 branch  | cou
---------+-----
    7973 |  34
    8387 |  32
    8446 |  32
    8447 |  32
    8448 |  31
   61397 |  31
   62438 |  32
   63689 |  31

Upvotes: 0

Views: 2048

Answers (1)

Angelo Fuchs
Angelo Fuchs

Reputation: 9941

You have to understand that SQL works in the way that you must know what you want before you can design the query.

In your question you write that you are looking for jobs that are not in jobstuff but now that we have the answer here, its clear that you were looking for branches that are not in jobstuff. My advice to you is: Take you time to word (in your language, or in English but not in SQL) exactly what you want BEFORE trying to implement it. When you are more experienced that isn't necessary always but for a beginner its the best way to learn SQL.

The Solution:

The thing here is that you don't need views to cascade queries, you can just select from inner queries. Also to filter elements based on a computed value (like count) can be done by the having clause.

The count(DISTINCT ...) causes duplicate entries to be only counted once, so if a Job is in a term twice, it now gets counted only once.

The query below selects all branches that ever got a jobstaff and then looks for jobs that are not in this list.

As far as I understood your question this should help you:

SELECT branch, count(DISTINCT term_id) as cou
FROM jobs j
WHERE j.branch NOT IN (SELECT branch FROM job WHERE job.id IN (select jobid FROM jobstaff))
GROUP BY branch
HAVING count(DISTINCT term_id) > 10

Upvotes: 2

Related Questions