Counting database items with join - sql

Using ORMLite, I want to count the number of database items that fit certain criteria. A simplified version of my database is as follows:
Employee Table:
employeeId
departmentId
Department Table:
departmentId
Salary Table:
employeeId
payGrade
Suppose I want to count the number of employees from a subset of departments that are at certain pay grade. When I try something like the following, I get an exception reporting that only one select column is allowed.
salaryQB.selectColumns(salaryQB.EMPLOYEE_ID);
salaryQB.where().eq(salaryQB.PAY_GRADE, 12);
employeeQB.where.in(Employee.DEPARTMENT_ID, departmentList)
.and().in(employeeQB.EMPLOYEE_ID, salaryQB);
employeeQB.setCountOf(true);
count = dao.countOf(employeeQB.prepare());
But code like this returns the following error:
RuntimeException (java.sql.SQLException: Inner query must have only 1
select column specified instead of 2)
Is there any way to do this short of writing a raw SQL query?

Hrm. I can't see any problems with your code #Jeff. I've improved the exception message in ORMLite to show the actual field names for the future but that won't help you right now:
Inner query must have only 1 select column specified instead of 2: [id, foreign]
The message is [obviously] trying to tell you that you have specified more than one selectColumns(...) in the salaryQB inner QueryBuilder. But you seem to be only selecting one column here:
salaryQB.selectColumns(salaryQB.EMPLOYEE_ID);
I don't see where the salaryQB is defined but maybe there is some more code somewhere else that also is using selectColumns? I've tried to reproduce the error in the testInnerCountOf() method towards the bottom of the QueryBuilderTest unit test but it seems to work fine.
If you can reproduce this in a unit test or if you can see how my unit test differs from your config then let me know.
Edit:
As of version 4.22 (from 9/2012), ORMLite now supports simple JOIN statements. So your query can be simplified to:
salaryQB.where().eq(salaryQB.PAY_GRADE, 12);
employeeQB.join(salaryQB);
employeeQB.where().in(Employee.DEPARTMENT_ID, departmentList);
employeeQB.setCountOf(true);
count = dao.countOf(employeeQB.prepare());

Related

MS Access SQL code - query issue with NOT IN

I'm trying to find out which partners has not paid the monthly tuition in a particular month.
I have a table called Socios containing all partners names SocioNome and another table called RegistroPagamento contaning all payments done (This particular table is fulfilled by a form where the user input the Partner Name, Amount Paid and which particular month/year the payment is related to).
I have created a query where I used the SQL code below:
SELECT [SocioNome]
FROM [Socios] NOT IN
(SELECT [SocioNome] FROM [RegistroPagamento] WHERE [MesBoleto] = [Forms]![Selecionar_MCobranca]![TBoxMes] AND [AnoBoleto] = [Forms]![Selecionar_MCobranca]![TBoxAno]);
[Selecionar_MCobranca] is the form I have mentioned before and the [TBoxMes] & [TBoxAno] are the combo boxes from the form which the user can select the month and the year the payment refers to.
When I run the code, a error message pops up indicating that there is a FORM clause syntax issue, and I don't know exactly what is causing the problem.
NOT IN is a comparison operator in the WHERE clause. It does not belong in the FROM cluase. I strongly recommend using NOT EXISTS instead. The idea is:
SELECT s.SocioNome
FROM Socios as s
WHERE NOT EXISTS (SELECT 1
FROM RegistroPagamento as rp
WHERE rp.MesBoleto = [Forms]![Selecionar_MCobranca]![TBoxMes] AND
rp.AnoBoleto = [Forms]![Selecionar_MCobranca]![TBoxAno] AND
rp.SocioNome = s.SocioNome
);
NOT IN returns no rows if any row in the subquery is NULL. To protect against this, just use NOT EXISTS. It has the expected behavior in this case.

Display Student's firstname and course enrolled by him in Oracle

people the question is to write a query to display the student's first name alone with the course name that they have registered. Sort the result based on student's first name and course name.
Here is my attempt to solve the problem,
select FirstName,CourseName from student s
inner join registration r on s.StudID=r.StudId
inner join course c on r.CourseID=c.CourseID
order by FirstName asc,CourseName asc;
This is the schema for the tables
The output i get when i run the code is this
Where am i going wrong? please help people.
From your comment:
the output seems to be printing two tables as you can see in the picture i think they should be printed in the same table
No, it isn't. You appear to be using SQL/Plus and its all part of the same output; its just that after a certain number of rows SQL/Plus will re-print the column headers.
The commands for SQL/Plus are given here and you should be able to use:
SET PAGESIZE 10000
(Or some other large value) and that will set the number of rows that SQL/Plus will output before it repeats the headers. Then you can re-run your query and the repeated headers will not be printed.
I did this and got the required output.
select FirstName,CourseName from ((student s
inner join registration r on s.StudID=r.StudId)
inner join course c on r.CourseID=c.CourseID)
order by FirstName asc,CourseName asc;

I'm Stuck on this Oracle Query ( Shows no data when run )

so I'm trying to answer this query in my oracle database . I'm quite new to SQL.
My Query is to List the full details of the cinemas managed by the employees with the employee number 52 and 55.
I have the test data for this in both the employee and Cinema table which correlates with one another.
However, when I run the statement it just shows the selected column names with no data . And when I run the script it says no rows selected. ( Even though I've commited my changes to my test data in both tables ).
Below is the code I've used.
SELECT Cinema.Cinema_no , Cinema.Cinema_Name , Cinema.Location , Cinema.Managerempno
FROM CINEMA
INNER JOIN employee ON Cinema.Cinema_no = employee.emp_no
WHERE Cinema.Managerempno = '52' AND Cinema.Managerempno = '55' ;
Please let me know if I've gone completely wrong with this. Or whether I need to change something within it. Thank you
Use IN:
SELECT c.Cinema_no, c.Cinema_Name, c.Location, c.Managerempno
FROM CINEMA c
WHERE c.Managerempno IN (52, 55);
Notes:
You don't need the JOIN. The employee number is in the Managerempno column.
Table aliases make queries easier to write and to read.
Empno is -- presumably -- a number. So, don't use single quotes around the constants.

Is there a way to select automatically the row pointed by an FK on a given table?

Today while writing one of the many queries that every developer in my company write every day I stumbled upon a question.
The DBMS we are using is Sql Server 2008
Say for example I write a query like this in the usual PERSON - DEPARTMENT db example
select * from person where id = '01'
And this query returns one row:
id name fk_department
01 Joe dp_01
The question is: is there a way (maybe using an addon) to make sql server write and execute a select like this
select * from department where id = 'dp_01'
only by for example clicking with the mouse on the cell containing the fk value (dp_01 in the example query)? Or by right click and selecting something like ("Go to pointed value")?
I hope I didn't wrote something stupid or impossible by definition
Not really, but that seems like a silly thing to do. Why would you want to confuse an id with a department name?
Instead, you could arrange things so you could do:
select p.*
from person p
where department = 'dp_01';
You would do this by adding a computed column department that references a scalar function that looks up the value in the department table. You can read about computed columns here.
However, a computed column would have bad performance characteristics. In particular, it would basically require a full table scan on the person table, even if that is not appropriate.
Another solution is to create a view, v_person that has the additional columns you want. Then you would do:
select p.*
from v_person p
where department = 'dp_01';
Why can't you write yourself by saying
select * from department where id =
(select fk_department from person where id = '01')

SQL query: HAVING, GROUP BY

I have two tables. One with a list of shops and their ID's (shop_id)
and one with a list of employees with the ID (shop_id) of the shop they work at.
I have to print out each employee with a certain position form a certain shop.
My query is normally correct but I seem to get an error like tblEmployees.
Normally my query would look something like.
SELECT tblEmployees.Name, tblEmployees.Surname, tblShops.shop_id
FROM tblEmployees, tblShops
GROUP BY tblEmployees.shop_id
HAVING tblEmployees.shop_id = tblShops.shop_id;
Normally I get an error saying something like:
tblEmployees.Name is not part of an aggregate function.
What I want to know is if it would solve my problem if I put every column that gives me this error under the GROUP BY statement. Or is there another way of fixing this error without it affecting the result I need to get from this query.
Drop the GROUP BY and HAVING clauses. You aren't aggregating here. You want to be joining your tables.
SELECT tblEmployees.Name, Surname, tblShops.shop_id
FROM tblEmployees JOIN tblShops
ON tblEmployees.shop_id=tblShops.shop_id