Access Sql insert subquery not working - sql

I'm designing a web form to publish to a SharePoint webpage in Microsoft Access 2010. I have a form that uses a combo box to select a team name. I need to enter the team id corresponding to that team name into the employee table. This is what I have so far:
INSERT INTO Employee ( Employee_Name, Team_ID )
VALUES ([Forms]![Add Employee]![txtName], (SELECT MAX(Team.Team_ID)
FROM Team, Employee
WHERE [Team]![Team_Name]=[Forms]![Add Employee]![cmbxTeam]));
It gives me an error saying
Query input must contain at least one table or query.
How do I fix this?

You can either use the VALUES clause to specify hard coded values, or you can use a SELECT statement to generate the stuff that will be inserted. Here you are combining the two. Instead:
INSERT INTO Employee ( Employee_Name, Team_ID )
SELECT
[Forms]![Add Employee]![txtName],
MAX(Team.Team_ID)
FROM Team, Employee
WHERE [Team]![Team_Name]=[Forms]![Add Employee]![cmbxTeam];
Slightly unrelated, why are you cross joining employees and teams, when you don't need the Employee table in your SELECT?
This should be equivalent and much much faster:
INSERT INTO Employee ( Employee_Name, Team_ID )
SELECT
[Forms]![Add Employee]![txtName],
MAX(Team.Team_ID)
FROM Team
WHERE [Team]![Team_Name] = [Forms]![Add Employee]![cmbxTeam];

Related

SQL Query Involving Data From Different Tables

I have two different tables with records I need to join together in a way I can't quite figure out how to make work. My data looks like this.
Table A
Columns: Employee_ID, Employee_Department, Employee_Team, Manager_ID, Is_a_Manager ... many other columns
Sample Values:
12345 Department1 Team1 67890 Yes/No
.
.
.
One employee per row, several thousand rows comprising the entire company
Table B
Employee_ID, Manager_ID ... other columns
The exact same data set as Table A
Currently I'm combining those two tables (and three others) with a simple join on Employee_ID, which I'm then using as a data source in Tableau to visualize the data.
What I'd like to do with a SQL script is as follows:
Check to see whether an employee in Table A is a manager or not based on the Is_a_Manager column
If they are, find an employee in Table B who is one of their direct reports by matching the employee ID in Table A to the Manager ID in Table B.
Lookup that direct report's department and team in Table A by matching the Employee_ID in Table B to Employee_ID in Table A and displaying the Employee_Department and Employee_Team columns.
Add the direct report's department and team to two new columns in the original manager's Table A row
I'd like the final output in Table A to be something like
Employee_ID, Employee_Department, Employee_Team, Manager_ID, Is_a_Manager? ... Direct_Report_Department, Direct_Report_Team
Also, an important point is that some managers will have employees who are on different teams, so values in the Direct_Report_Department and Direct_Report_Team are not distinct. I only actually need any one employee's Department and Team to display, it doesn't matter which employee's it is.
Finally, I am able to do step 1 fairly easily in Tableau, so if the SQL script could do steps 2-4 and simply return a null value if the employee was not a manager, that would work for me as well.
Any ideas on how to accomplish this would be greatly appreciated. Thank you!
This should work based on the requirement provided. You don’t have to do any of the steps in Tableau and can simply export the output from the SQL as your data source
Select Tb1.Employee_ID, Tb1.Employee_Department, Tb1.Employee_Team, Tb1.Manager_ID, Tb1.Is_a_Manager, Tb3. Direct_Report_Department, Tb3. Direct_Report_Team
from Table_A Tb1
join (Select Manager_id, max(Employee_id) as emp_id from Table_B group by Manager_id) Tb2
on Tb1.Employee_id = Tb2.Manager_id
left join (Select Employee_ID, Employee_Department as Direct_Report_Department, Employee_Team as Direct_Report_Team from Table_A group by Employee_ID, Employee_Department, Employee_Team) Tb3
on Tb2.emp_id = Tb3.Employee_ID
where Tb1.Is_a_Manager = 'Yes';

is There a Column Count Property in VB.net like MS Access?

I am working with vb.net and DataBase
Let us say I have two related tables:
Employee(EmpID, EmpName, DepID as ForeignKey)
Department(DepID,DepName)
And I want to show the table Employee in a Datagrid, but I need to show the department name instead of the department ID, as can be done in MS Access So easly By setting Column Count to 2, and Column Width to 0;1
Since it is annoying and sometimes we cannot memorize what does the ID refers to.
How Can it Be Done?
Thanks for advance :)
Your best bet is to write a an sql query in your datasource this way:
select EmpID, EmpName, Employee.DepID ,DepName
from Employee inner join Department
on Employee.DepID=Employee.DepID
in your Datagrid replace DepID with DepName in source view.

Generate "scatter plot" result of members against sets from SQL query

I have a staff database table containing staff members, with user_no and user_name columns. I have another, department, table containing the departments which staff can be members of, with dept_no and dept_name as columns.
Because staff can be members of multiple departments, I have a third, staff_dept, table with a user_no column and a dept_no column, which are the primary keys of those other two tables. This table shows which departments each member of staff belongs to and contains one row for each user/department intersection.
I would like to have an output in the form of a spreadsheet (CSV file, whatever; I'll be fine mangling the results into a usable form after I've got them) with one column for each department, and one row for each user, with an X appearing at each intersection, as defined in staff_dept.
Can I write a single SQL query which will achieve this result? or will I have to do some "real" programming (because it's not a "real" program until you've nested three or four for loops, obviously) to collect and format this data?
This can be done with a PIVOT table (using SQL Server):
SELECT user_name, [dept1name], [dept2name], [dept3name], ...
FROM
(SELECT s.user_name, d.dept_name,
case when sd.user_no is not null then 'X' else '' end as matches
from staff s
cross join department d
left join staff_dept sd on s.user_no = sd.user_no and d.dept_no = sd.dept_no
) AS s
PIVOT
(
min(matches)
FOR dept_name IN ([dept1name], [dept2name], [dept3name], ...)
) AS pvt
order by user_name
Demo: http://www.sqlfiddle.com/#!3/c136d/5
Edit: To generate the PIVOT query dynamically from the list of departments in the table, you would make use of dynamic SQL, i.e., generate the code into a variable and use sp_executesql helper stored procedure. Here's an example: http://www.sqlfiddle.com/#!3/c136d/14
In SQL Server (if you're using SQL Server), I would start with a full outer join (to include all staff and departments, not just those involved in the relation), drop that into a pivot statement to pivot all departments into columns, and then build a short script to generate and dynamically execute that SELECT statement (because the columns created by a pivot statement must be hard-coded, they can't be dynamically generated at run time).
Here's a sample -- it's an unpivot statement, but the concept is pretty much the same.

SQL to get rows (not groups) that match an aggregate

Given table USER (name, city, age), what's the best way to get the user details of oldest user per city?
I have seen the following example SQL used in Oracle which I think it works
select name, city, age
from USER, (select city as maxCity, max(age) as maxAge
from USER
group by city)
where city=maxCity and age=maxAge
So in essence: use a nested query to select the grouping key and aggregate for it, then use it as another table in the main query and join with the grouping key and the aggregate value for each key.
Is this the standard SQL way of doing it? Is it any quicker than using a temporary table, or is in fact using a temporary table interanlly anyway?
What you are using will work, although it displays all users which share the max age.
You can do this in a slightly more readable way using the row_number() ranking function:
select name, city, age
from (
select
city
, age
, row_number() over (partition by city order by age) as rn
from USER
) sub
where rn = 1
This will also select at most one user per city.
Most database systems will use a temporary table to store the inner query. So I don't think a temporary table would speed it up. But database performance is notoriously hard to predict from a distance :)

Qlikview joins that doesn't join on all matching column names

I'm new to Qlikview and looking for some answers regarding scripting. How can I create Qlikview joins that just join on a specific column (and not all that are having a matching name)? Let's say that I'm having the following tables:
Employee
Id | Person | DepartmentID | Flags
1000 , Bob , 2001 , 1000000
1001 , Sue , 2002 , 1100000
Department
Id | Name | Flags
2001 , HR , 01101111
2001 , R&D , 1100000
What is the best way of joining those tables on the DepartmentID <-> ID field? The data is provided by SQL selects. I'm thinking of writing SQL views using unique names would be one idea, but there must be a simpler way. Please advise.
Karl
First, you really will be better off using the QlikCommunity for these questions, the forum is very well supported by the QlikView user community and you'll get answers quicker, the only reason I found this is that I have a google alert on QlikView.
To your question:
QlikView will automatically create a join on all matching fields and there is no way to stop it doing this, there is also no way to make it join using fields of different names. The answer therefore is to rename your fields in either the SQL Select statement or in the LOAD statement, for example:
Employee:
LOAD ID AS EmpID, Person, DepID, Flags AS Emp_Flags;
SQL SELECT ID, Person, DepartmentID as DepID, Flags FROM .........;
Department:
LOAD ID AS DepID, Name AS DepartmentName, Flags AS Dep_Flags;
SQL SELECT ID, Name, Flags FROM .........;
This should do the trick for you.
One more piece of advice, although QlikView will join on multiple fields it is best to avoid this, so if you do have a join that requires multiple fields then you should create a key specifically for the QlikView table by adding fields together in both table to create a single field.
As I said above, join the QlikCommunity (www.qlikcommunity.com) and you'll find a much better service for your questions.
There is a way to prevent QlikView from joining fields with similar names automatically.
Say, if you two tables Tab1 and Tab 2 with similar field names, however different in their own context, you could use the "noconcatenate" keyword to prevent QlikView from automatically making an association.
you can edit the load script in QlikView (CTRL+E) and use something like this:
Work:
LOAD
EmployeeId,
EmployeePerson,
DepatmentId,
EmployeeFlags,
DepartmentName,
DepartmentFlags
SELECT Employee.Id as EmployeeId, Employee.Person as EmployeePerson, Employee.DepartmentID as DepatmentId, Employee.Flags as EmployeeFlags, Department.Name as DepartmentName, Department.Flags as DepartmentFlags
FROM Employee, Department
WHERE Employee.DepartmentID = Department.Id
(Did not try it, but you should get the idea)
This should work
employee:
LOAD * INLINE [
ID, Person, DepartmentID, Flags
1000, Bob, 2001, 1000000
1001, Sue, 2002, 1100000
];
department:
LOAD * INLINE [
ID, Name, Flags
2001, HR, 01101111
2002, R&D, 1100000
];
left join (employee)
LOAD ID AS DepartmentID,
Name,
Flags AS Department_Flags
Resident department
;
DROP Table department;
The result shoud look like this:
Kind Regards
Daniel