Skip to content

Commit 593edc3

Browse files
authored
Update company.tsql
1 parent d4be4c9 commit 593edc3

1 file changed

Lines changed: 365 additions & 1 deletion

File tree

T-Sql/company.tsql

Lines changed: 365 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,9 @@ VALUES (501, 3, '2023-12-15', 4.5, 1, 'Excellent performance in sales targets. G
167167
INSERT INTO PERFORMANCE_REVIEW(reviewId, empId, reviewDate, rating, reviewerEmpId, comments)
168168
VALUES (502, 6, '2023-12-16', 4.2, 1, 'Consistently meets targets. Could improve on documentation.');
169169

170-
170+
-- ========================================
171+
-- SELECT QUERIES
172+
-- ========================================
171173
-- Sample queries
172174
-- Find all employees in Sales department
173175
SELECT * FROM EMPLOYEE WHERE dept = 'Sales';
@@ -191,3 +193,365 @@ FROM EMPLOYEE e
191193
LEFT JOIN ATTENDANCE a ON e.empId = a.empId
192194
WHERE MONTH(a.workDate) = MONTH(GETDATE()) AND YEAR(a.workDate) = YEAR(GETDATE())
193195
GROUP BY e.name;
196+
-- ========================================
197+
-- ALTER TABLE / UPDATE COLUMN TYPE QUERIES
198+
-- ========================================
199+
200+
-- Increase the size of varchar columns
201+
ALTER TABLE DEPARTMENT ALTER COLUMN deptName VARCHAR(50);
202+
ALTER TABLE DEPARTMENT ALTER COLUMN location VARCHAR(100);
203+
204+
-- Change email column to accommodate longer email addresses
205+
ALTER TABLE EMPLOYEE ALTER COLUMN email VARCHAR(100);
206+
207+
-- Expand project name and status fields
208+
ALTER TABLE PROJECT ALTER COLUMN projectName VARCHAR(100);
209+
ALTER TABLE PROJECT ALTER COLUMN status VARCHAR(25);
210+
211+
-- Increase performance review comments field
212+
ALTER TABLE PERFORMANCE_REVIEW ALTER COLUMN comments VARCHAR(1000);
213+
214+
-- Add new columns to existing tables
215+
ALTER TABLE EMPLOYEE ADD isActive BIT DEFAULT 1;
216+
ALTER TABLE EMPLOYEE ADD terminationDate DATE NULL;
217+
218+
ALTER TABLE PROJECT ADD projectManager INT NULL;
219+
ALTER TABLE PROJECT ADD FOREIGN KEY (projectManager) REFERENCES EMPLOYEE(empId);
220+
221+
ALTER TABLE DEPARTMENT ADD budget DECIMAL(15,2) NULL;
222+
223+
-- For SQL Server, to change data type of a column with data:
224+
-- First, create a new column with the desired type
225+
ALTER TABLE PROJECT_ASSIGNMENT ADD hoursAllocatedNew DECIMAL(7,2);
226+
-- Copy data from old column to new column
227+
UPDATE PROJECT_ASSIGNMENT SET hoursAllocatedNew = hoursAllocated;
228+
-- Drop the old column
229+
ALTER TABLE PROJECT_ASSIGNMENT DROP COLUMN hoursAllocated;
230+
-- Rename the new column to the original name
231+
EXEC sp_rename 'PROJECT_ASSIGNMENT.hoursAllocatedNew', 'hoursAllocated', 'COLUMN';
232+
233+
234+
-- ========================================
235+
-- COMPLEX SELECT QUERIES WITH CTEs
236+
-- ========================================
237+
238+
-- 1. Employee Hierarchy with Recursive CTE
239+
WITH EmployeeHierarchy AS (
240+
-- Anchor member: Top-level managers
241+
SELECT empId, name, managerId, jobTitle, 0 as Level
242+
FROM EMPLOYEE
243+
WHERE managerId IS NULL
244+
245+
UNION ALL
246+
247+
-- Recursive member: Employees under managers
248+
SELECT e.empId, e.name, e.managerId, e.jobTitle, eh.Level + 1
249+
FROM EMPLOYEE e
250+
INNER JOIN EmployeeHierarchy eh ON e.managerId = eh.empId
251+
)
252+
SELECT empId, name, jobTitle, Level,
253+
REPLICATE(' ', Level) + name AS HierarchicalName
254+
FROM EmployeeHierarchy
255+
ORDER BY Level, name;
256+
257+
258+
-- 2. Department Performance Analysis with Multiple CTEs
259+
WITH DeptSalary AS (
260+
SELECT d.deptId, d.deptName,
261+
AVG(s.amount) as avgSalary,
262+
MIN(s.amount) as minSalary,
263+
MAX(s.amount) as maxSalary,
264+
COUNT(e.empId) as empCount
265+
FROM DEPARTMENT d
266+
JOIN EMPLOYEE e ON d.deptId = e.deptId
267+
JOIN SALARY s ON e.empId = s.empId
268+
GROUP BY d.deptId, d.deptName
269+
),
270+
DeptProjects AS (
271+
SELECT d.deptId,
272+
COUNT(DISTINCT p.projectId) as projectCount,
273+
SUM(p.budget) as totalBudget,
274+
AVG(p.budget) as avgProjectBudget
275+
FROM DEPARTMENT d
276+
LEFT JOIN PROJECT p ON d.deptId = p.deptId
277+
GROUP BY d.deptId
278+
)
279+
SELECT ds.deptName,
280+
ds.empCount,
281+
ds.avgSalary,
282+
ds.minSalary,
283+
ds.maxSalary,
284+
COALESCE(dp.projectCount, 0) as projectCount,
285+
COALESCE(dp.totalBudget, 0) as totalProjectBudget,
286+
COALESCE(dp.avgProjectBudget, 0) as avgProjectBudget
287+
FROM DeptSalary ds
288+
LEFT JOIN DeptProjects dp ON ds.deptId = dp.deptId
289+
ORDER BY ds.avgSalary DESC;
290+
291+
292+
-- 3. Employee Workload Analysis
293+
WITH EmployeeProjects AS (
294+
SELECT e.empId, e.name, e.deptId,
295+
COUNT(pa.projectId) as projectCount,
296+
SUM(pa.hoursAllocated) as totalHours
297+
FROM EMPLOYEE e
298+
LEFT JOIN PROJECT_ASSIGNMENT pa ON e.empId = pa.empId
299+
GROUP BY e.empId, e.name, e.deptId
300+
),
301+
ProjectDetails AS (
302+
SELECT pa.empId,
303+
STRING_AGG(p.projectName, ', ') as projectList
304+
FROM PROJECT_ASSIGNMENT pa
305+
JOIN PROJECT p ON pa.projectId = p.projectId
306+
GROUP BY pa.empId
307+
)
308+
SELECT ep.name,
309+
d.deptName,
310+
ep.projectCount,
311+
ep.totalHours,
312+
pd.projectList,
313+
CASE
314+
WHEN ep.totalHours > 40 THEN 'Overallocated'
315+
WHEN ep.totalHours BETWEEN 30 AND 40 THEN 'Fully Allocated'
316+
WHEN ep.totalHours BETWEEN 15 AND 29 THEN 'Partially Allocated'
317+
ELSE 'Underallocated'
318+
END as AllocationStatus
319+
FROM EmployeeProjects ep
320+
JOIN DEPARTMENT d ON ep.deptId = d.deptId
321+
LEFT JOIN ProjectDetails pd ON ep.empId = pd.empId
322+
ORDER BY ep.totalHours DESC;
323+
324+
325+
-- 4. Salary Ranking within Departments
326+
WITH SalaryRanking AS (
327+
SELECT e.empId, e.name, d.deptName, s.amount,
328+
RANK() OVER (PARTITION BY d.deptId ORDER BY s.amount DESC) as salaryRank,
329+
DENSE_RANK() OVER (PARTITION BY d.deptId ORDER BY s.amount DESC) as denseRank,
330+
ROW_NUMBER() OVER (PARTITION BY d.deptId ORDER BY s.amount DESC) as rowNum,
331+
PERCENT_RANK() OVER (PARTITION BY d.deptId ORDER BY s.amount DESC) as percentRank
332+
FROM EMPLOYEE e
333+
JOIN DEPARTMENT d ON e.deptId = d.deptId
334+
JOIN SALARY s ON e.empId = s.empId
335+
)
336+
SELECT name, deptName, amount,
337+
salaryRank,
338+
CASE
339+
WHEN percentRank <= 0.25 THEN 'Top 25%'
340+
WHEN percentRank <= 0.50 THEN 'Top 50%'
341+
WHEN percentRank <= 0.75 THEN 'Top 75%'
342+
ELSE 'Bottom 25%'
343+
END as SalaryPercentile
344+
FROM SalaryRanking
345+
ORDER BY deptName, salaryRank;
346+
347+
348+
-- 5. Project Timeline Analysis
349+
WITH ProjectStatus AS (
350+
SELECT projectId, projectName,
351+
startDate, endDate, budget, status,
352+
DATEDIFF(day, startDate, endDate) as durationDays,
353+
DATEDIFF(day, startDate, GETDATE()) as daysElapsed,
354+
CASE
355+
WHEN endDate < GETDATE() AND status != 'Completed' THEN 'Overdue'
356+
WHEN endDate >= GETDATE() AND status = 'In Progress' THEN 'On Track'
357+
WHEN status = 'Completed' THEN 'Completed'
358+
ELSE 'Not Started'
359+
END as ProjectHealth
360+
FROM PROJECT
361+
),
362+
ProjectTeam AS (
363+
SELECT p.projectId,
364+
COUNT(DISTINCT pa.empId) as teamSize,
365+
SUM(pa.hoursAllocated) as totalAllocatedHours
366+
FROM PROJECT p
367+
LEFT JOIN PROJECT_ASSIGNMENT pa ON p.projectId = pa.projectId
368+
GROUP BY p.projectId
369+
)
370+
SELECT ps.projectName,
371+
ps.status,
372+
ps.ProjectHealth,
373+
ps.durationDays,
374+
ps.daysElapsed,
375+
CAST(ps.daysElapsed * 100.0 / NULLIF(ps.durationDays, 0) AS DECIMAL(5,2)) as PercentComplete,
376+
ps.budget,
377+
pt.teamSize,
378+
pt.totalAllocatedHours
379+
FROM ProjectStatus ps
380+
LEFT JOIN ProjectTeam pt ON ps.projectId = pt.projectId
381+
ORDER BY ps.ProjectHealth DESC, ps.endDate;
382+
383+
384+
-- 6. Employee Tenure and Salary Growth Analysis
385+
WITH EmployeeTenure AS (
386+
SELECT empId, name, hireDate,
387+
DATEDIFF(year, hireDate, GETDATE()) as yearsOfService,
388+
DATEDIFF(month, hireDate, GETDATE()) as monthsOfService
389+
FROM EMPLOYEE
390+
),
391+
SalaryHistory AS (
392+
SELECT et.empId, et.name, et.yearsOfService,
393+
s.amount as currentSalary,
394+
s.amount / NULLIF(et.yearsOfService, 0) as avgYearlyIncrease
395+
FROM EmployeeTenure et
396+
JOIN SALARY s ON et.empId = s.empId
397+
)
398+
SELECT name, yearsOfService, currentSalary,
399+
COALESCE(avgYearlyIncrease, currentSalary) as avgYearlyIncrease,
400+
CASE
401+
WHEN yearsOfService < 2 THEN 'New Employee'
402+
WHEN yearsOfService BETWEEN 2 AND 5 THEN 'Mid-Level'
403+
ELSE 'Senior Employee'
404+
END as TenureCategory
405+
FROM SalaryHistory
406+
ORDER BY yearsOfService DESC;
407+
408+
409+
-- 7. Department Cross-Analysis
410+
WITH DepartmentMetrics AS (
411+
SELECT d.deptId, d.deptName,
412+
COUNT(DISTINCT e.empId) as employeeCount,
413+
COUNT(DISTINCT p.projectId) as projectCount,
414+
COALESCE(SUM(p.budget), 0) as totalProjectBudget,
415+
AVG(s.amount) as avgSalary
416+
FROM DEPARTMENT d
417+
LEFT JOIN EMPLOYEE e ON d.deptId = e.deptId
418+
LEFT JOIN PROJECT p ON d.deptId = p.deptId
419+
LEFT JOIN SALARY s ON e.empId = s.empId
420+
GROUP BY d.deptId, d.deptName
421+
),
422+
DepartmentEfficiency AS (
423+
SELECT deptId,
424+
CASE
425+
WHEN employeeCount > 0 THEN totalProjectBudget / employeeCount
426+
ELSE 0
427+
END as budgetPerEmployee,
428+
CASE
429+
WHEN projectCount > 0 THEN employeeCount * 1.0 / projectCount
430+
ELSE 0
431+
END as employeesPerProject
432+
FROM DepartmentMetrics
433+
)
434+
SELECT dm.deptName,
435+
dm.employeeCount,
436+
dm.projectCount,
437+
dm.totalProjectBudget,
438+
dm.avgSalary,
439+
de.budgetPerEmployee,
440+
de.employeesPerProject
441+
FROM DepartmentMetrics dm
442+
JOIN DepartmentEfficiency de ON dm.deptId = de.deptId
443+
ORDER BY dm.totalProjectBudget DESC;
444+
445+
446+
-- 8. Performance Review Insights
447+
WITH ReviewStats AS (
448+
SELECT e.empId, e.name, e.deptId,
449+
COUNT(pr.reviewId) as reviewCount,
450+
AVG(pr.rating) as avgRating,
451+
MIN(pr.rating) as minRating,
452+
MAX(pr.rating) as maxRating
453+
FROM EMPLOYEE e
454+
LEFT JOIN PERFORMANCE_REVIEW pr ON e.empId = pr.empId
455+
GROUP BY e.empId, e.name, e.deptId
456+
),
457+
DeptAvgRating AS (
458+
SELECT deptId,
459+
AVG(avgRating) as deptAvgRating
460+
FROM ReviewStats
461+
WHERE avgRating IS NOT NULL
462+
GROUP BY deptId
463+
)
464+
SELECT rs.name,
465+
d.deptName,
466+
rs.reviewCount,
467+
rs.avgRating,
468+
dar.deptAvgRating,
469+
CASE
470+
WHEN rs.avgRating > dar.deptAvgRating THEN 'Above Department Average'
471+
WHEN rs.avgRating = dar.deptAvgRating THEN 'At Department Average'
472+
WHEN rs.avgRating < dar.deptAvgRating THEN 'Below Department Average'
473+
ELSE 'No Reviews'
474+
END as PerformanceLevel
475+
FROM ReviewStats rs
476+
JOIN DEPARTMENT d ON rs.deptId = d.deptId
477+
LEFT JOIN DeptAvgRating dar ON rs.deptId = dar.deptId
478+
ORDER BY CASE WHEN rs.avgRating IS NULL THEN 1 ELSE 0 END, rs.avgRating DESC;
479+
480+
481+
-- 9. Attendance Pattern Analysis
482+
WITH AttendanceStats AS (
483+
SELECT empId,
484+
COUNT(*) as daysPresent,
485+
AVG(DATEDIFF(hour, timeIn, timeOut)) as avgHoursWorked,
486+
MIN(timeIn) as earliestArrival,
487+
MAX(timeOut) as latestDeparture
488+
FROM ATTENDANCE
489+
WHERE workDate >= DATEADD(month, -1, GETDATE())
490+
GROUP BY empId
491+
),
492+
EmployeeAttendance AS (
493+
SELECT e.empId, e.name, d.deptName,
494+
COALESCE(a.daysPresent, 0) as daysPresent,
495+
COALESCE(a.avgHoursWorked, 0) as avgHoursWorked,
496+
a.earliestArrival,
497+
a.latestDeparture
498+
FROM EMPLOYEE e
499+
JOIN DEPARTMENT d ON e.deptId = d.deptId
500+
LEFT JOIN AttendanceStats a ON e.empId = a.empId
501+
)
502+
SELECT name, deptName, daysPresent, avgHoursWorked,
503+
FORMAT(earliestArrival, 'HH:mm') as earliestArrival,
504+
FORMAT(latestDeparture, 'HH:mm') as latestDeparture,
505+
CASE
506+
WHEN avgHoursWorked >= 9 THEN 'Overtime Worker'
507+
WHEN avgHoursWorked BETWEEN 7.5 AND 9 THEN 'Regular Hours'
508+
WHEN avgHoursWorked > 0 THEN 'Part Time'
509+
ELSE 'No Recent Attendance'
510+
END as WorkPattern
511+
FROM EmployeeAttendance
512+
ORDER BY avgHoursWorked DESC;
513+
514+
515+
-- 10. Comprehensive Employee Dashboard
516+
WITH EmployeeSummary AS (
517+
SELECT e.empId, e.name, e.jobTitle, d.deptName,
518+
s.amount as salary,
519+
DATEDIFF(year, e.hireDate, GETDATE()) as yearsOfService
520+
FROM EMPLOYEE e
521+
JOIN DEPARTMENT d ON e.deptId = d.deptId
522+
LEFT JOIN SALARY s ON e.empId = s.empId
523+
),
524+
ProjectSummary AS (
525+
SELECT pa.empId,
526+
COUNT(DISTINCT pa.projectId) as activeProjects,
527+
SUM(pa.hoursAllocated) as totalHours
528+
FROM PROJECT_ASSIGNMENT pa
529+
JOIN PROJECT p ON pa.projectId = p.projectId
530+
WHERE p.status = 'In Progress'
531+
GROUP BY pa.empId
532+
),
533+
ReviewSummary AS (
534+
SELECT empId,
535+
AVG(rating) as avgRating,
536+
MAX(reviewDate) as lastReviewDate
537+
FROM PERFORMANCE_REVIEW
538+
GROUP BY empId
539+
)
540+
SELECT es.name,
541+
es.jobTitle,
542+
es.deptName,
543+
es.salary,
544+
es.yearsOfService,
545+
COALESCE(ps.activeProjects, 0) as activeProjects,
546+
COALESCE(ps.totalHours, 0) as projectHours,
547+
rs.avgRating,
548+
rs.lastReviewDate,
549+
CASE
550+
WHEN rs.lastReviewDate < DATEADD(year, -1, GETDATE()) OR rs.lastReviewDate IS NULL
551+
THEN 'Review Overdue'
552+
ELSE 'Review Current'
553+
END as reviewStatus
554+
FROM EmployeeSummary es
555+
LEFT JOIN ProjectSummary ps ON es.empId = ps.empId
556+
LEFT JOIN ReviewSummary rs ON es.empId = rs.empId
557+
ORDER BY es.name;

0 commit comments

Comments
 (0)