Access Query IIf Value in Values returned by another Query - ms-access

I have a Query that looks up an Employee ID, Employee Name and Team Name from the current Staff Database. I have another Query that lists all unique values in Team Name. (Team Name is an Integer, and corresponds to Employee ID, also an Integer.)
Eg this is how teams are structured. Emp ID 100 belongs to Emp ID 10's team. 10 belongs to 5. 5 belongs to 1, etc.
EmpID = 100
TeamName = 10
EmpID = 10
TeamName = 5
EmpID = 5
TeamName = 1
What I am trying to do is return a fourth field, giving an asterisk, "*", when the Emp ID also appears in the Team Name query (Thus meaning they have a team/are a Manager).
I have a DCount that works, but it is slower than I'd like, and will only get slower as the Database grows, but it might serve to explain what I need.
Expr1: IIf(DCount("TeamName","jdbo_MostRecentEmpDataRemain","TeamName = " & [EmpID])>0,"*","")
jdbo_MostRecentEmpDataRemain is a Query that returns all data for staff that are active.
This will return an Asterisk if the EmpID has team members assigned to them, and nothing if they do not.
I'm wondering if this can be applied through queries to make it faster. Please let me know if you have any suggesstions.
I tried this: Expr2: IIf([EmpID] In ([qryListOfTeams].[TeamName]),"a","z")
but that returns lots of z's and then an a, as it seems to return a value for every value that is in the Team List. I want it to aggregate those and display an a if there is an a, otherwise a z. (Where in the original "*" is the a, and "" is the z)
Kind regards,
Jamie Warburton

How about:
SELECT * FROM TableOrQuery
LEFT JOIN (SELECT DISTINCT EmpID FROM Teams
WHERE EmpID In (SELECT TeamName FROM Teams)) As a
ON TableOrQuery.EmpID = a.EmpID
Derived tables are usually faster than subqueries.
EDIT re comment
Asterisk has a specific meaning, so while you can do this, I do not recommend it.
SELECT TableOrQuery.*, a.IsTeam FROM TableOrQuery
LEFT JOIN (SELECT DISTINCT EmpID, "*" As IsTeam FROM Teams
WHERE EmpID In (SELECT TeamName FROM Teams)) As a
ON TableOrQuery.EmpID = a.EmpID

Related

Mysql command for showing a single column from two table (same named column in both table) with using two different condition

The database name is employee-information in that database I was trying to show one "person_name" column that is available in both tables "works" & "employee" by using two different conditions that will filter values in each table.
So that I can see the values filtered by the two conditions from both tables in one single "person_name" column.
work & employee tables,
Here is what I have done so far,
USE employee_information;
SELECT employee.person_name, works.person_name
FROM employee, works
WHERE city = "Miami" AND salary > 50000;
The result I am getting,
For that command I am getting this two-column from both table. Conditions are working but values are repetitive and there are two columns but I need to show one column filled with the value from both tables where those two conditions are true
My desired result is,
person_name//table name
Alex //values those are true by both condition in each table
Robin Hood
You need to join the tables using person_name as the relationship.
SELECT employee.person_name
FROM employee
JOIN works ON employee.person_name = works.person_name
WHERE employee.city = 'Miami' AND works.salary < 50000;
In your case you can use JOIN , here is example
SELECT w.*,e.company_name,e.salary FROM works w INNER JOIN employee e ON e.person_name = w.person_name WHERE city = "Miami" AND salary > 50000;
you must add a primary key in "employee table" with name id
and a foreign key in "work table" with name employee_id
and your query will be
SELECT employee.person_name
FROM employee
WHERE employee.id, works.employee_id
and city = "Miami" AND salary > 50000;

MySQL query returned 0 rows

I have a task to make a database only in MySQL. I made 11 tables and connected them via foreign keys. I tried to make a simple query in order to return name and lastname of the patient in his diagnose, but I always get only a header with the first and last name and analysis.
The patient's table has nameID, name, last name, ID serial number, date of birth and so on, but I wanted only name and last name for the test query.
The second table I joined is analysis, which has analysisID, patientID, doctorID, hospitalID, diagnosis and so on.
My query is like this:
SELECT pat.name, pat.lastname
FROM patient pat
JOIN analysis a ON pat.patientID = a.patientID
group by a.analysisID
order by pat.lastname
This query returns 0 rows. Please help, I am new at mySQL. I read a lot of tutorials, read posts here about this problem and I still didn't find a solution.
I assume that you want to eliminate any duplicate analysisID's for the same person with the use of group by. If so, you could use the following:
Select a.analysisID, pat.name, pat.lastname
from patient pat, analysis a
where pat.patientID = a.patientID
group by a.analysisID, pat.name, pat.lastname
What the above query will do is return only one record when the analysisID, name and lastname are all the same.

sql table design to fetch records with multiple inclusion and exclusion conditions

We want to select customers based on following parameters i.e. customer should be in:
specific city i.e. cityId=1,2,3...
specific customerId should be excluded i.e. customerId=33,2323,34534...
specific age i.e. 5 years, 7 years, 72 years...
This inclusion & exclusion list can be any long.
How should we design database for this:
Create separate table 'customerInclusionCities' for these inclusion cities and do like:
select * from customers where cityId in (select cityId from customerInclusionCities)
Some we do for age, create table 'customerEligibleAge' with all entries of eligible age entries:
i.e. select * from customers where age in (select age from customerEligibleAge)
and Create separate table 'customerIdToBeExcluded' for excluding customers:
i.e. select * from customers where customerId not in (select customerId from customerIdToBeExcluded)
OR
Create One table with Category and Ids.
i.e. Category1 for cities, Category2 for CustomerIds to be excluded.
Which approach is better, creating one table for these parameters OR creating separate tables for each list i.e. age, customerId, city?
IN ( SELECT ... ) can be very slow. Do your query as a single SELECT without subqueries. I assume all 3 columns are in the same table? (If not, that adds complexity.) The WHERE clause will probably have 3 IN ( constants ) clauses:
SELECT ...
FROM tbl
WHERE cityId IN (1,2,3...)
AND customerId NOT IN (33,2323,34534...)
AND age IN (5, 7, 72)
Have (at least):
INDEX(cityId),
INDEX(age)
(Negated things are unlikely to be able to use an index.)
The query will use one of the indexes; having both will give the Optimizer a choice of which it thinks is better.
Or...
SELECT c.*
FROM customers AS c
JOIN cityEligible AS b ON b.city = c.city
JOIN customerEligibleAge AS ce ON c.age = ce.age
LEFT JOIN customerIdToBeExcluded AS ex ON c.customerId = ex.customerId
WHERE ex.customerId IS NULL
Suggested indexes (probably as PRIMARY KEY):
customers: (city)
customerEligibleAge: (age)
customerIdToBeExcluded: (customerId)
In order to discuss further, please provide SHOW CREATE TABLE for each table and EXPLAIN SELECT ... for any of the queries actually work.
If you use the database only that operation, I recommend to use the first solution. Also the first solution is very simple to deploy.
The second solution fills up with junk the DB.

How to select all subjects that are taken by all students such that all students took grade > 50 in them

I have a table called records containing 3 columns: student, subject and grade
Each {x,y,z} entry in the table means student x took class y with grade z. If student x didn't take class y then the entry doesn't exist in the table. So this table is like a university record of all students and the subjects taken by them.
I want to select all subjects that are taken by all students such that the grades of all students in these subjects are above 60.
I tried creating the table
CREATE TABLE temp SELECT subject FROM records WHERE grade > 60;
Then I used temp to create a new table that has subject and count, where count counts the number of students that took that subject, and then I deleted all rows that have count< number of students. But I know this is very inefficient.
How can I do this more efficiently using MySQL ?
Also if you can provide me with good MySQL resource/tutorial link so that I can practice, I would be thankful. I am new to MySQL and I am working on large databases and I need to make my queries more efficient and straight forward.
How about
SELECT subject FROM records
WHERE subject NOT IN
(
SELECT subject FROM records
WHERE grade <=60
)
AND subject IN
(
SELECT subject FROM records
GROUP BY subject
HAVING count(*) = (SELECT COUNT(DISTINCT student) FROM records)
)
As further reading I'd recommend this and this
EDITED: now includes "subjects taken by ALL students"
I would use the no exists clause because it simply confirms if there are no records within the subquery, but will not try to obtain the resultset. It is more effective than a not in clause.
SELECT subject FROM records r1
WHERE subject NOT EXISTS
(
SELECT 1 FROM records r2
WHERE r2.subject=r1.SUBJECT AND grade<=60
)

Database schema & pulling info

I'm far from being a database expert, so please feel free to let me know I'm doing it entirely wrong. I'm trying to create a set of tables that has the following basic rules:
There are companies, managers and employees. Managers can only belong to one company, but employees can belong to more then one manager. The table structure I've come up with is something like this:
# Companies
company_id
company_name
# Managers
manager_id
company_id
# Employees
employee_id
company_id
employee_name
# Managed By
employee_id
manager_id
Does this structure seem reasonable? I thought I need something like "Managed By" since an employee can have multiple managers.
What I'm boggling on is now how do I manage to grab the records I'd want. For example:
Get all employee names belonging to a certain manager
Get all employee names belonging to two certain managers
All employees to the same company
edit: I think I'm getting the queries figured out but this still feels unweidy, so any help on the table structure would be appreciated.
The fact I'm having problems writing queries for this information makes me think I've done something fundamentally wrong with the table structure. Hopefully someone here can set me right?
Generally, the scheme is correct. The one possibility that does exist, however, is that you could have data where an employee is managed by managers at more than two companies.
For your queries:
select distinct Employees.employee_name as name from Employees, Managers, ManagedBy where Managers.manager_id = X and ManagedBy.manager_id = Managers.manager_id and Employees.employee_id = ManagedBy.employee_id;
and
select distinct Employees.employee_name as name from Employees, Managers, ManagedBy where (Managers.manager_id = X or Managers.manager_id = Y) and ManagedBy.manager_id = Managers.manager_id and Employees.employee_id = ManagedBy.employee_id;
where X and Y are the manager IDs you want.
edit: I know you crossed out the queries you wanted, but the third one is this:
select distinct Employees.employee_name as name from Employees where Employees.company_id = Z;
where Z is the company ID you want.
All employees to the same company
SELECT employee_id, employee_name, company_name
FROM Employees
LEFT JOIN Companies ON Employees.company_id = Companies.company_id
WHERE Companies.company_id = ????
or if you pulling by name
WHERE Companies.company_name = 'ABC'
Get all employee names belonging to a certain manager
SELECT employee_id, employee_name, manager_id
FROM Employees
LEFT JOIN Managed_By ON Employees.employee_id = Managed_By.employee_id
WHERE Managed_By.manager_id = ????
manager_name in Managers table would be nice to have