SQL COUNT entries related to 3 tables - sql

I had this sql statement running for these two tables: tblStations and tblThreads, for counting number of Stations in each thread:
SELECT tblThreads.*, (SELECT COUNT(*) FROM tblStations WHERE tblStations .fldThreadID=tblThreads.fldID) AS TotalStationsInThread FROM tblThreads;
and then display tblThread.Name and TotalStationsInThread, for each thread in the system.
Now I added another table (tblUsers) in this hierarchy:
each thread can have many users, and each user can have many stations.
The three tables are related to each other by this:
tblStations.fldUserID=tblUsers.fldID > tblUsers.fldThreadID=tblThreads.fldID.
So I changed my SQL query to this:
SELECT tblThreads.*, (SELECT COUNT(*) FROM tblStations WHERE tblStations.fldUserID=tblUsers.fldID AND tblUsers.fldThreadID=tblThreads.fldID) AS TotalStationsInThread FROM tblThreads;
But now I'm getting this message: "No value given for one or more required parameters." It's like the database can't connect the tables tblStations with tblThreads via tblUsers...
Any help please on how to count the number of stations that are connected to all the users that are connected to each thread??

This is the correct answer for MS Access Jet Database Engine:
SELECT tblThreads.*, (SELECT COUNT(tblStations.fldUserID) FROM tblStations INNER JOIN tblUsers ON tblStations.fldUserID = tblUsers.fldID WHERE tblUsers.fldThreadID = tblThreads.fldID) AS TotalStationsInThread FROM tblThreads;
Many thanks for Gordon Linoff for his answer.

You need to include tblUsers in the from clause:
SELECT tblThreads.*,
(SELECT COUNT(*)
FROM tblUsers inner join
tblStations
on tblStations.fldUserID = tblUsers.fldID
WHERE tblUsers.fldThreadID = tblThreads.fldID
) AS TotalStationsInThread
FROM tblThreads;

Related

Can we select data from 2 tables in same time

From the code as shown below. I wonder that why it can select data from 2 tables in same time that are table "venue AS v" and table "as s".
or I misunderstand?
SELECT name, s.num_match
FROM venue AS v,
(SELECT venue_id, COUNT(*) AS num_match
FROM match
GROUP BY venue_id) AS s
WHERE v.venue_id = s.venue_id
LIMIT 3;
Yes you can using JOIN clause for example.
More infos here: https://www.informit.com/articles/article.aspx?p=30875&seqNum=5
Yes you can select data from as many as tables you want at the same time.
In this case you are trying to get an aggregated number from table-s and join it with the table v.
There are many ways to write the code to join the table. Above is one method which you have used.

SQL Subquery help for a noob

I work in recruiting and would like to get a list of jobs that are posted to multiple offices along with the names of those offices per job.
I started with the query below to identify the jobs with multiple offices. What is my next step for showing offices.name for only jobs with multiple offices? Bonus if I can get one record per job and have the office names fill into columns. I'm using SQL Workbench connected to Amazon Redshift. Thanks much!
select jobs_offices.job_id, count(offices.id)
from jobs_offices join offices on jobs_offices.office_id = offices.id
group by jobs_offices.job_id
having count(offices.id) >1
order by count(offices.id) DESC
Your query looks good so far, it is just missing the office name? I believe you could get a comma-separated list of the offices by adding the listagg function. Something like select jobs_offices.job_id, listagg(offices.name, ', ') from ...
Redshift docs
you can use corelated subquery
select t.* from offices t
where exists ( select 1 from jobs_offices t1 where t1.office_id=t.id
group by t1.job_id
having count(*) >1
)

Write an SQL query search

I need to write a sql query that will find users that have at least 2 different books from set of (book1, book2 and book3) . what technique can be used to write such a query?
I want to find all users who own at least 2 books from a specified set of books ('book_1','book_2','book_3') but do not own any of the books in a second specified set ('book_4')?
EDIT:
OP couldn't explain what he is actually looking for. What OP actually trying to do is:
Find all users who own at least 2 different books and exclude those users who has a book called 'book_4'.
Try this:
SELECT Users,Count(DISTINCT Books) as CountOfBooks
FROM TableName
GROUP BY Users
HAVING COUNT(DISTINCT Books) >= 2
Explanation:
Here, we are grouping the table contents with users field and counting the number of distinct books that each user has. The HAVING clause is helpful to filter the result with the count of distinct book.
You can change the number 2 with the count you need. And = can be used for exact match instead of atleast.
See an example in SQL Fiddle.
EDIT:
For excluding users with book_4, try this:
SELECT Users,Count(DISTINCT Books) as CountOfBooks
FROM TableName
WHERE Users NOT IN (SELECT Users FROM TableName WHERE Books = 'book_4')
GROUP BY Users
HAVING COUNT(DISTINCT Books) >= 2
OR a faster version (without using IN):
SELECT T1.Users,Count(DISTINCT T1.Books) as CountOfBooks
FROM TableName T1 LEFT JOIN
(SELECT Users
FROM TableName
WHERE Books = 'Book4') T2 ON T2.Users=T1.Users
WHERE T2.Users IS NULL
GROUP BY T1.Users
HAVING COUNT(DISTINCT T1.Books)>=2
An example in SQL Fiddle.
Try this,
select USERS,count(distinct BOOKS) from myTable
where BOOKS in('Book1','Book2','Book3')
group by USERS
having count(distinct BOOKS) >=2

Divide select in SQL does not work

Can you help me please with the divide select in SQL? I use the Oracle Apex Express Edition. I have three tables. In English (original names are in brackets): User (Uzivatel), Event (Udalost) and Groups of users (Skupina_u). Their context is on screens:
Now I have to use divide select in SQL. This select is formulated: You must show all users who were on all events. In my tables, you can see that I have two users, who were on all events. They are part of group “SK2.” I am using this select:
select *
from Uzivatel
where not exists (select *
from Skupina_u
where not exists (select *
from Udalost
where Skupina_u.ID_uz = Uzivatel.ID_uz
and Skupina_u.ID_uz = Udalost.ID_uz))
But the result is: no data found.
Thank you for help.
This is answering the question you pose in English . . . "Find all users who are on all events."
This is an example of a set-within-sets query. I think the best approach is using aggregation (because the same structure can be used for many questions). Let me show you using the English names for the tables and columns:
select eu.UserId
from User_Events eu
group by eu.UserId
having count(distinct eu.EventId) = (select count(*) from Events e)
That is, select all the users where the number of distinct event ids is the number in the events table. If you only want events that have users, then use the following having clause:
having count(distinct eu.EventId) = select count(distinct eventId) from Events e)

How to compute difference between the values of thecolumns of two tables

I have two tables: T_Guest, T_Table
In T_Guest I have a list of the guests. Each guest has an ID (g_no) and ID of a table (t_no) to which the guest is related.
It is possible that to the same table will be related many guests.
In the T_Table I have a list of the tables. Each table has an ID (t_no) and a field n_places that describes how many places that table does have.
QUESTION:
I need to build an SQL query (in MS Access), which will show a list of a tables ID's which are still have a free sits.
I have an idea to find first the list of the tables which are full, and than just to implement EXCEPTION on that group from the whole group of the available tables.
But to compute how many tables does have ZERO free places, I need somehow to compute for each table:
n_places - NUMBER_OF_GUESTS_ON_THAT_TABLE
Where the last one (NUMBER_OF_GUESTS_ON_THAT_TABLE) it's just:
SELECT COUNT(*)
FROM T_Table INNER JOIN T_Guest ON T_Table.t_no = T_Guest.t_no
GROUP BY T_Table.t_no
But I don't how to implement DIFFERENCE n_places - NUMBER_OF_GUESTS_ON_THAT_TABLE
Can somebody help me with that kind of a task???
You can use the guest count as a derived table:
SELECT t.t_no, t.n_Places-Nz(g.Guests,0) As FreePlaces
FROM T_Table t
LEFT JOIN (
SELECT t_no,COUNT(*) as Guests
FROM T_Guest
GROUP BY t_no) g
ON t.t_no = g.t_no
To get tables with spaces, you can add:
WHERE t.n_Places-Nz(g.Guests,0)>0
SELECT [tt].[t_no]
FROM T_Table AS tt
WHERE (SELECT COUNT(*) FROM T_Guest AS tg WHERE tg.t_no = tt.t_no) < tt.n_places
Should work in access, uses a subquery but given the context I don't think this will be an issue.
This is classic for the HAVING clause:
SELECT t_no FROM T_Guest GROUP BY t_no
HAVING COUNT(*)<(SELECT T_Table.n_Places FROM T_Table WHERE T_Table.t_no=T_Guest.t_no)