update employee as a
set a.sup_role=(
select b.job_role from employee as b
where b.supervisorid=a.employeeid
group by b.job_role
order by count(b.job_role) desc
limit 1
)
where a.job_role='MAN1';
OK I have a table of all of our employees - around 100K.
All of our users have job roles that I built based on their employee.job_title. So based on 4K+ job_titles I knock that down to about 40 job_roles. This is so we can assign things in our CMS based on employee.job_roles. This has been working good but the problem is with the managers. The managers get some generic corporate job_title that we role into a generic job_role.
What you see above is code that I use to kind of do what I need to do - find out what job_role a supervisor based on what "most of their employees do". This outputs the correct sup_role but there are several things wrong with my code:
based on my syntax it won't let me update the employee table directly. I have have to update an employee "helper" table and fill in later.
So it is parsing through for the job_role "MAN1". First I don't want to update this to add new manager job roles. Also this doesn't account for my company doing ad hoc things like a manager just have a regular job title or different NULL fields.
And then the last part is that this code is taking 6 minutes to go through. Luckily I run this as a batch job but I am afraid it might cause crashes.
So I have the following table -
employee
with applicable fields
employeeid
supervisorid
job_title
job_role
sup_role
So below is my last attempt. It just runs and never outputs anything. I am wondering if I need to create a helper table to grab the DISTINCT supervisorid's since one employee could be many people's supervisor.
update employee as a
set a.sup_role=(
select b.job_role from employee as b
where b.supervisorid=a.employeeid
group by b.job_role
order by count(b.job_role) desc
limit 1
)
WHERE a.uid IN (select DISTINCT employee.supervisorid
from employee
where employee.supervisorid is not null
);
Related
Hi I have run in to a problem when retrieving a particular data set using 3 tables in a MySql database.Tables are as follows
Student
SID | Name | Age | Telephone
Term
TID | Start | End
Payment
PID | TID | SID | Value
SID is primary key of Student table. TID is primary key of Term table. PID is primary key of Payment table. TID and SID in Payment table are foreign key references.
Student table contains data of students. Term table contain data of term start and end dates. Payment table contain data about student payment. Records in Payment table may either contain TID or not. When it is a registration payment there will be no TID. Otherwise it is a term fee and there will be TID. What I want is a list of students that hasn't paid this terms fees until today. Asuume this TID is in a variable. How can I obtain the list of students ? IT SEEMS SUPER EASY. BUT I COULDNT FIND AN ANSWER THIS WHOLE DAY 😣
You want a list of just those students who do not have a TID-populated record whose start and end dates are either side of today, in Payment
SELECT * FROM
student
LEFT OUTER JOIN
(select * from payment where TID is not null and NOW() BETWEEN start and end) this_term_payments
on student.id = this_term_payments.sid
WHERE
this_term_payments.ID is null
There are many ways to skin this cat. Here is one. We filter the payments table down to just a list of this term's payments (that's the inner query). And left join that to students. Left join means we get all students, matched with this_term_payments if the this_term_payments row exists, or NULL in every this_term_payments column if the term payment doesn't exist. The where clause then filters the whole results set down to "just those who don't have a term payment" by looking for those nulls that the left join creates
FWIW, your question attracted close votes because it didn't include example data/demonstrate the level of your effort we like to see on SQL questions. If you'd included sample data for all your tables and an example result set you wanted to see out, it means we can write an exact query that meets your requirements.
This is a bit of a double edged sword for me; we can deliver exactly what you ask for even if you later realise it's not what you want (asking in English is far more vague than giving an example result set) but at the same time we basically become some free outsourced homework contractor or similar, doing your work for you and removing learning opportunities along the way. Hopefully you'll take this query (it's likely it doesn't output everything you want, or outputs stuff you don't want) and craft what you want out of it now that the technique has been explained.. :)
For an SQL question that was relatively well received (by the time i'd finished editing it following up on the comments), and attracted some great answers take a look here:
Fill in gaps in data, using a value proportional to the gap distance to data from the surrounding rows?
That's more how you need to be asking SQL questions - say what you want, give example data, give scripts to help people create your same data so they can have a play with their idea without the boring bits of creating the data first. I picked on that one because I didn't even have any SQL attempts to show at the time; it was just a thought exercise. Having nothing working isn't necessarily a barrier to asking a good question
Try this:
select s.name, p.value from Student s, Term t, Payment p where t.TID = p.TID and s.SID=p.SID and p.TID is null;
I am working on an employee management/reward system and need to be able to show a single "transaction history" page that shows in chronological order the different events that the employee has experienced in one list. (Sort of like how in facebook you can goto your history/action section and see a chronological list of all the stuff that you have done and affects you, even though they are unrelated to eachother and just have you as a common user)
I have different tables for the different events, each table has an employee_id key and an "occured" timestamp, some table examples:
bonuses
customers
raise
complaints
feedback
So whenever an event occurs (ie a new customer is assigned to the employee, or the employee gets a complaint or raise) a new row is added to the appropriate table with the employee ID it affects and a timestamp of when it occured.
I need a single query to pull all records (upto 50 for example) that include the employee and return a history view of that employee. The field names are different in each table (ie the bonus includes an amount with a note, the customer includes customer info etc).
I need the output to be a summary view using column names such as:
event_type = (new customer, bonus, feedback etc)
date
title (a brief worded title of the type of event, specified in sql based on the table its referencing)
description (verbiage about the action, such as if its event_type bonus display the bonus amount here, if its a complain show the first 50 characters of the complaint message or the ID of the user that filed the complaint from the complaints table. All done in SQL using if statements and building the value of this field output based on which table it comes from. Such as if its from the customers table IF current_table=customers description='A customer was assigned to you by'.customers.assigner_id).
Ideally,
Is there any way to do this?
Another option I have considered, is I could do 5-6 different queries pulling the records each from their own table, then use a mysql command to "mesh/interleave" the results from all the queries into one list by chronological order. That would be acceptable too
You could use a UNION query to merge all the information together and use the ORDER BY clause to order the actions chronologically. Each query must have the same number of fields. Your ORDER BY clause should be last.
The examples below assume you have a field called customer_name in the customers table and bonus_amount in the bonuses table.
It would look something like this:
SELECT 'New Customer' as event_type, date,
'New customer was assigned' as title,
CONCAT('New Customer: ', customer_name, ' was assigned') as description
FROM customers
WHERE employee_id = 1
UNION
SELECT 'Bonus' as event_type, date,
'Received a bonue' as title,
CONCAT('Received a bonus of $', FORMAT(bonus_amount, 2), '.') as description
FROM bonuses
WHERE employee_id = 1
UNION
...
ORDER BY date DESC;
I am writing a query to extract results from a table with a condition to exclude some results from the table.
Ex: I have a table with students name column (100 students). I want to run a query to extract details of 95 students and exclude 5 students. Could you help me out with this?.
Here is more information:
Thanks for your answer. I am sorry if my question was unclear.
Here is more information what I am trying to run.
I have a task queue ID
Task Queue 1 = Documents manually processed.
Task Queue 2 = Documents exported to another application
Task Queue 2 includes documents manually processed and documents automatically processed to another application. I am trying to run total number of documents exported to another application (Task Queue 2) and exclude Task Queue 1 from these results.
I tried the code as given below , but I did not get any results.
Select WorkQueueHistory.id from WorkQueueHistory where
TaskId='2' NOT IN( Select WorkQueueHistory.id from WorkQueueHistory where TaskId='20') and
creationStampUtc>='2013-01-01 00:00:00.000'
and creationStampUtc<='2013-12-31 00:00:00.000'
WorkqueueHistory is the table
TaskID is the task number
I want to run results from taskID 2 but want to exclude task ID 20.
could you help me out with this?.
What criteria do you have for excluding the 5 students? That is kind of the key here
For example, if you wanted to exclude all of the men you might do
SELECT Name, Gender FROM Students WHERE Gender = 'Male'
Or to exclude those called Mark maybe
SELECT Name FROM Students WHERE Name LIKE '%Mark %'
But it depends on the criteria
UPDATE: *with specifics to update, something along these lines (without seeing your table)
SELECT q2.DocName
FROM Queue2 q2
WHERE q2.Id NOT IN (SELECT Id FROM Queue1)
Assuming you have an Id column or something which is common across both queues - you need some common identifier be it name or Id
I have a faculty table, and each faculty has a certain number of students under him/her. So there is a 'current' column, which is the number of students currently under them.
However, I don't want to ++ and -- every time I switch a student to another faculty. Is there a way to keep the column updated with a query that uses count()? I find it is easier and more accurate to use the query 'select count() from student where advisor = 2' for example that using my current column.
To do this, use a view:
CREATE VIEW studentCount AS
SELECT
profID,
profName,
whatever,
(SELECT COUNT(*)
FROM studentTable
WHERE studentTable.profID=profTable.profID
) AS studentCount
FROM profTable;
Obviously, this needs to be massaged a little to fit your schema, but essentially, setup your view to have all the columns of the table with the faculty info and add a column at the end that counts the number you want in it.
Triggers could be a solution to you problem?
http://dev.mysql.com/doc/refman/5.5/en/triggers.html
You could create a trigger that automaticly updates your faculty table every time a student switch faculty.
I have a bunch of records (orders) that I want to make available to users to make reports from.
The users come from different departments, and I would like to make it, so each department can only see their own stuff.
I can't figure out how to do this the right way.
What I have now is:
- A model where I have placed a Filter on the Order table.
The filter can use GetUserID() to get the users name, but I can't figure out how I get from that to the "UserDepartment" table that maps users to specific departments.
Ofcourse, I would prefer a solution whereby I didn't have to create new access groups or edit the model for each department that someone might dream up.
Any clues?
(Using SQL server 2008)
EDIT: This link http://blogs.msdn.com/bobmeyers/articles/Implementing_Data_Security_in_a_Report_Model.aspx shows the basics of what I'm trying to do, but the author seems to assume that each record have a UserName field that can be matched.
In my case i want all users of department X to be able to access the line.
We had a similar problem to this and ended up writing a function in SQL.
The function did the following:
Received the username parameter from SRSS
Performed a lookup on the permissions table and retrieved the records (department Id's in your case).
returned the department Id's
Then our sql statement looked like this:
SELECT *
FROM ImportantData
WHERE DepartmentId IN (SELECT Id FROM fn_GetUserDepartmentAllocations(#UserName))
This did force us to modify all of the sql queries but it allowed us to do it with minimal complex logic.
The other thing that this allows for is if you have one user who transcends department boundaries: for example a manager of 2 departments.
CREATE FUNCTION [dbo].[fn_GetUserDepartmentAllocations]
(
#UserName NVARCHAR(100)
)
RETURNS
#TempPermissions TABLE
(
DepartmentId Int
)
AS
BEGIN
INSERT INTO #TempPermissions
SELECT DepartmentId
FROM DepartmentPermissions
WHERE DepartmentAllowedUsername = #UserName
RETURN
END
The main benefit to doing it this way is it also allows you to edit one place to change the entire permissions structure, you don't have to go through each and every report to change it, instead you change one place
For example you could have a manager who belongs to 2 departments but is not allowed to view them except on thursdays (I know silly example but you get the point hopefully).
Hope this helps
Pete
This assume that Users have Orders.
So, filter by users who exist in the same dept as the filter user. Don't filter orders directly.
I've guessed at schema and column names: hoep you get the idea...
SELECT
MY STuff
FROM
Order O
JOIN
UserDept UD ON O.UserCode = UD.UserCode
WHERE
EXISTS (SELECT *
FROM
UserDept UD2
WHERE
UD2.UserCode = #MYUSerCode
AND
UD2.DeptID = UD.DeptID)
--or
SELECT
MY STuff
FROM
Order O
JOIN
UserDept D ON O.UserCode = D.UserCode
JOIN
UserDept U ON D.DeptID = U.DeptID
WHERE
U.UserCode = #MYUSerCode
What you're trying to achieve is difficult using the GetUserID() method. To use that your source query would have to return a lot of redundant data, imagine something like the following:
/*
Table: User
Fields: UserID, LoginName, FullName
Table: Department
Fields: DepartmentID, Name
Table: UserDepartments
Fields: UserID, DepartmentID
Table: Order
Fields: OrderNumber, DepartmentID
*/
SELECT O.OrderNumber, O.DepartmentID, U.LoginName
FROM Order O
JOIN Department D ON D.DepartmentID = O.DepartmentID
JOIN UserDepartments UD ON UD.DepartmentID = D.DepartmentID
JOIN User U ON U.UserID = UD.UserID
This will give you more rows than you want, basically a copy of the order for each user in the department that owns the order.
Now you can apply your filter as described in the link you provided. This will filter it down to just one copy of the order rows for the current user if they're in the right department.
If this is a performance issue there's other alternatives, easiest being using a local report (.RDLC) in either ASP.NET, WinForms or WPF and passing user details off to the data call so the filtering can be done in the SQL.