SQL Join two tables using versioned data - sql

I have two tables, both of which have a record date as part of the key. When the record is edited, a new version of it with the current RecordDate and whatever other changes were made is created. This applies to both tables. The RecordDate is not used as a foreign key at all only applies to its own table.
So for this example, Kate gets married, her employee record is updated to reflect her new surname. She is also taken off the fish counter and given a cushy job in management and so her Employee Task also changes.
Employee
CompanyId EmployeeId RecordDate Name
1 1 2011/04/11 Kate Windsor
1 1 2010/07/04 Kate Middleton
EmployeeTasks
CompanyId EmployeeId RecordDate TaskId TaskCode
1 1 2015/09/18 1 bbb
1 1 2015/09/18 1 aaa
I can select the most recent set of records for a single table, I can join one of these tables with another non versioned table but what I cannot figure out how to do is to join both these tables together such that I get data for the most recent records for each, so that it would return something like this?
CompanyId EmployeeId Name TaskId TaskCode
1 1 Kate Windsor 1 bbb
FWIW Im using an Oracle DB.

It's a bit messy, but you need to get down to just the employee and company IDs with a max record date for each. With the MAX date from each table those can be used to join back to the base tables and pull only the related records.
SELECT e.companyID, e.employeeID,
FROM (SELECT companyID, employeeID, MAX(RecordDate) AS maxDate
FROM employee
GROUP BY companyID, employeeID
) e
INNER JOIN (SELECT companyID, employeeID, MAX(RecordDate) AS maxDate
FROM employeeTasks
GROUP BY companyID, employeeID
) et ON e.companyID = et.companyID AND e.employeeID = et.employeeID
INNER JOIN employee emp
ON e.companyID = emp.companyID AND e.employeeID = emp.employeeID AND emp.RecordDate = e.maxDate
INNER JOIN employeeTask oN empT
ON et.companyID = empT.companyID AND et.employeeID = empT.employeeID AND empT.RecordDate = et.maxDate
Sorry for the initial, incomplete post, my fingers got away from me and accidentally submitted too soon!

Related

SQL Server : replace several instances of userID with username

I may be overthinking this but I have not managed to figure it out or find a solution, so I'm hoping for a pointer in the right direction. I tried using the Select ColumnA AS Column B etc but it's not doing what I want.
I have 2 tables, scenario examples below
Table 1 (Vehicle)
VehicleID (001)
VehicleMake (Ford)
VehicleModel (Falcon)
VehicleExCleanEmpID (005)
VehicleIntCleanEmpID (003)
Table 2 (Employee)
EmpID (005)
EmpName (Dave)
The scenario being that a vehicle is cleaned internally or externally by any one of a pool of employees shown by the relevant ID in the Vehicles table.
I want to show in a query VehicleID, InsideCleanName, ExternalCleanName rather than showing the employee's ID.
So end up with results similar to this
VehicleID InsideCleanName ExternalCleanName
------------------------------------------------
001 Bob Dave
002 Sue Dave
003 John Sid
Thanks for any tips and or help
THat seems like a pretty simple query with two inner joins to the Employee table - something like this:
SELECT
v.VehicleId,
InsideCleanName = e1.EmpName,
ExternalCleanName = e2.EmpName
FROM
dbo.Vehicle v
INNER JOIN
dbo.Employee e1 ON v.VehicleIntCleanEmpId = e1.EmpID
INNER JOIN
dbo.Employee e2 ON v.VehicleExCleanEmpId = e2.EmpID
Joining to the Employee e1 table is giving you the employee who was responsible for the inside cleaning, while joining a second time, to Employee e2 gives you the one responsible for the external cleaning.
Join the two table with EmpId and select the columns you want similar to the code below:
select column1, column2 from table1 inner join table2 on table1.EmpId = table2.EmpId

Two group by tables stich another table

I have 3 tables I need to put together.
The first table is my main transaction table where I need to get distinct transaction id numbers and company id. It has all the important keys. The transaction ids are not unique.
The second table has item info which is linked to transaction id numbers which are not unique and I need to pull items.
The third table has company info which has company id.
Now I've sold some of these with the first one through a group by id. The second through a subquery which creates unique ids and joins onto the first one.
The issue I'm having is the third one by company. I cannot seem to create a query that works in the above combinations. Any ideas?
As suggested here is my code. It works but that's because for the company I used count which doesn't give the correct number. How else can I get the company number to come out correct?
SELECT
dep.ItemIDAPK,
dep.TotalOne,
dep.company,
company.vendname,
appd.ItemIDAPK,
appd.ItemName
FROM (
SELECT
csi.ItemIDAPK,
sum(f.TotalOne) as TotalOne,
count(f.DimCurrentcompanyID) company
FROM dbo.ReportOne F with (nolock)
INNER JOIN dbo.DSaleItem csi with (nolock)
on f.DSaleItemID = csi.DSaleItemID
INNER JOIN dbo.DimCurrentcompany cv
ON f.DimCurrentcompanyID = cv.DimCurrentcompanyID
INNER JOIN dbo.DimDate dat
on f.DimDateID = dat.DimDateID
where (
dat.date >='2013-01-29 00:00:00.000'
and dat.date <= '2013-01-30 00:00:00.000'
)
GROUP BY csi.ItemIDAPK
) as dep
INNER JOIN (
SELECT
vend.DimCurrentcompanyID,
vend.Name vendname
FROM dbo.DimCurrentcompany vend
) As company
on dep.company = company.DimCurrentcompanyID
INNER JOIN (
SELECT
c2.ItemIDAPK,
ItemName
FROM (
SELECT DISTINCT ItemIDAPK
FROM dbo.dimitem AS C
) AS c1
JOIN dbo.dimitem AS c2 ON c1.ItemIDAPK = c2.ItemIDAPK
) as appd
ON dep.ItemIDAPK = appd.ItemIDAPK
For further information my output is the following example, I know the code executes and the companyid is incorrect as I just put it with a (count) in their to make the above code execute:
Current Results:
Item Number TLS CompanyID Company Name Item Number Item Name
111111 300 303 Johnson Corp 29323 Soap
Proposed Results:
Item Number TLS CompanyID Company Name Item Number Item Name
111111 300 29 Johnson Corp 29323 Soap

Joining and aggregating data from multiple tables

In customer table there is a SupportID which is the WorkerId in the worker Table, each WorkerId shows which will handle that customer.
Working Name | No. of accounts | total revenue
----------------------------------------------
John McCoy 20 10,000
Worker table contains - Firstname, Lastname, EmployeeId
Receipt table contains - receipt Id, CustomerId,
ReceiptLine Table contains - receiptlineId, receipt Id, Unitprice, quantity
At the moment I have this code / idea
SELECT FirstName, LastName
FROM Employee A, Invoice B
WHERE A.EmployeeId = B.CustomerId
In this question, you have not mention dependency among worker and receipt table. However, let the dependency column is workerId on table receipt. Now try this, hope you will get your desired result.
select a.firstName, sum(count(b.customerId)) as no_accounts, sum(c.unitPrice *c.quantity) as total_revenue
from (( worker a join receipt b on a.workerId = b.SupportId)
join receiptLine c on b.receiptId = c.receiptId) group by a.firstName order by a.firstName;
use GROUP BY to resolve your problem

Sql Query Join in Oracle

I have Parent table and multiple child tables with foreign key constraint.
School Table
School ID EduDetails Genders Address_id EDUTYPE
1 2 M 3 FGN
And the child tables like
Education Details
EDU ID EducationType
2 Online
AKA Name
School Id AKA Name
1 Test School
1 School Test
Gender Table
Gender ID Gender Desc
M Male
I am using Left outer join for the parent and school table to fetch the results.
But My issue is, If AKA table has 5 counts matching the school Id and Gender table has only 1 records for that school Id.
So the results comes with 5 duplicate rows with school Information and also other child table information.
Is there any workaround to fix this issue. I tried using subquery and row_number over by function. But it is not working for me. Can anybody help me to solve this issue.
Thanks in advance for your time in looking this issue.
My required output should be like this
School_id AKA Name GenderDesc EductaionType
1 Test School Male Online
1 School Test
So I need to have Null values for the not matching records.
Since you want all the records in the AKA Name table, I've joined on that getting a Row_Number for each row. Then using that Row_Number, LEFT JOIN on the other tables.
SELECT S.SchoolId,
SA.AKAName,
G.GenderName,
ED.EducationType
FROM School s
JOIN
(SELECT SchoolId,
AKAName,
ROW_NUMBER() OVER (PARTITION BY SchoolId ORDER BY AKAName) rn
FROM SchoolAKA
) SA ON S.SchoolID = SA.SchoolId
LEFT JOIN
(SELECT EDUID,
EducationType,
ROW_NUMBER() OVER (ORDER BY EducationType) rn
FROM EduDetails
) ED ON S.EDUID = ED.EDUID AND SA.rn = ED.rn
LEFT JOIN
(SELECT GenderId,
GenderName,
ROW_NUMBER() OVER (ORDER BY GenderName) rn
FROM Genders
) G ON S.GenderId = G.GenderId AND SA.rn = G.rn
Here is the SQL Fiddle.
And here are the results:
SCHOOLID AKANAME GENDERNAME EDUCATIONTYPE
1 School Test Male Online
1 Test School (null) (null)

NHibernate + join to derived table

In a table that stores multiple rows per employee, I want to pull one row per employee that represents the most recent entry for each employee. Here's where I am with hand-written SQL:
SELECT [all the selected columns here]
FROM Nominations t
inner join
(select max(NominationId) mostRecentNominationId,
EmployeeId from Nominations group by EmployeeId) n
on n.mostRecentNominationId = t_.NominationId
From source data like this:
nomination_id employee_id
-------------------------------
1 5
2 5
4 10
7 10
That'll give me something like this:
nomination_id employee_id
-------------------------------
2 5
7 10
I haven't been able to figure out how to accomplish that type of query via NHibernate ICriteria. Any thoughts?
Here is what you need to do:
DetachedCriteria dCriteria = DetachedCriteria.For<Nomination>("nomination")
.SetProjection(Projections.Max("nomination.Id"))
.Add(Restrictions.EqProperty("nomination.EmployeeId", "employee.Id"));
var nominations = Session.CreateCriteria<Nomination>("nom")
.CreateCriteria("Employee", "employee")
.Add(Subqueries.PropertyEq("nom.Id", dCriteria)).List<Nomination>();
This is not equilevant to the SQL query providfed in the question but it does exactly the same thing.
The SQL query that is generated by the above criteria query is:
SELECT *
FROM Nomination nom
inner join Employee employee on nom.EmployeeId=employee.EmployeeId
WHERE nom.NominationId =
(SELECT max(nomination.NominationId) as maxID
FROM Nomination nomination
WHERE nomination.EmployeeId = employee.EmployeeId)