How to Get ShiftCode base on time in and time out sql - sql

How do i automatically get Shiftcode based on this tables:
Shift Table:
enter image description here
Employee In and Out from Biometrics
enter image description here
Result Should be:
enter image description here
Currently to get shift code, timekeeper is manually entering it to the system.
i tried so many sql query specially BETWEEN, but its not working, I hope someone can help me on this. Thank you.

SELECT ISNULL(clockInShift.ShiftCode, 'N/A') ShiftCode, clockInShift.TransactionCode, TransactionDate
(SELECT ShiftCode, TransactionCode, TransactionDate
FROM SHIFTTABLE st, BIOMETRICS b
WHERE
TransactionFlag = 0 AND
TransactionTime BETWEEN ShiftIn - 0.5/24.0 AND ShiftIn +0.5/24.0) clockInShift
INNER JOIN
(SELECT ShiftCode, TransactionCode
FROM SHIFTTABLE st, BIOMETRICS b
WHERE
TransactionFlag = 1 AND
TransactionTime BETWEEN ShiftOut - 0.5/24.0 AND ShiftOut +0.5/24.0) clockOutShift
ON clockInShift.ShiftCode = clockOutShift.ShiftCode AND clockInShift.TransactionCode = clockOutShift.TransactionCode
This is without knowing any indecis or anything to make sure its fast enough or what timeframe you're looking for of course.

Wouldn't this work:
select
...
from
Shifts sh
inner join
Bioms bm
on bm.TransactionDateTime between sh.ShiftIn and coalesce(sh.BreakIn, sh.ShiftOut)
or
bm.TransactionDateTime between coalesce(sh.BreakOut,sh.ShiftIn) and sh.ShiftOut

Related

Sum up multiple values based off a single column

For context, I work in transportation. Also, I apologize for a poor title - I'm not exactly sure how to summarize my issue.
I am currently editing an existing report which returns a drivers ID, their name, when they were hired, and the total amount of miles they have driven since they have started at the company. It was brought to my attention that drivers who move within the company are assigned a different driverID, which is not counted towards their total miles driven. Using an example provided to me, I was indeed able to confirm this scenario, as indicated below:
DriverCode DriverName
----------- ----------------
WETDE Wethington,Dean
WETDEA Wethington,Dean
This is the query that gets the above (example driver is hardcoded at the moment):
select mpp.mpp_id as DriverCode,
mpp.mpp_lastfirst as DriverName
from manpowerprofile mpp
outer apply (select top 1 mpp_id
from manpowerprofile) as id
where mpp_firstname = 'Dean'
and mpp_lastname = 'Wethington'
This is the current query as it stands:
SELECT lh.lgh_driver1 as DriverCode
,m.mpp_lastfirst as DriverName
,m.mpp_hiredate as HireDate
,SUM(s.stp_lgh_mileage) as TotMiles
FROM stops s (nolock)
INNER JOIN legheader lh (nolock) on lh.lgh_number = s.lgh_number
INNER JOIN manpowerprofile m (nolock) on m.mpp_id = lh.lgh_driver1
/* OUTER APPLY ( SELECT top 1 mpp_id
FROM manpowerprofile) as id */
WHERE m.mpp_terminationdt > GETDATE()
AND m.mpp_id <> 'UNKNOWN'
AND lh.lgh_outstatus = 'CMP'
GROUP BY lh.lgh_driver1, m.mpp_lastfirst, m.mpp_hiredate
HAVING SUM(s.stp_lgh_mileage) > 850000
ORDER BY DriverCode DESC
What I'm looking to do is check to see if a name exists twice, and if it does, add both of those driver code's total miles together to return a single result for that individual driver. I'm a pretty novice SQL Developer still and have only now really started to delve into databases.
My current train of thought was to use an outer apply, but I'm sure there's a better way to do this.
As per your comment, leaving off the driver code and hire date...
(Because they could/would be different for the drivers being combined.)
SELECT
m.mpp_lastfirst as DriverName
,SUM(s.stp_lgh_mileage) as TotMiles
FROM
stops s (nolock)
INNER JOIN
legheader lh (nolock)
on lh.lgh_number = s.lgh_number
INNER JOIN
manpowerprofile m (nolock)
on m.mpp_id = lh.lgh_driver1
WHERE
m.mpp_terminationdt > GETDATE()
AND m.mpp_id <> 'UNKNOWN'
AND lh.lgh_outstatus = 'CMP'
GROUP BY
m.mpp_lastfirst
HAVING
SUM(s.stp_lgh_mileage) > 850000
ORDER BY
m.mpp_lastfirstDESC

SQL query join table clarification

I'm trying to join a columns from 2 different tables.
1st table is TBWORKFLOWPROCESS, column name is processname
2nd table is TBLSTAPP, column names are isforreconsideration, isforamendment
My query is:
select
pro.processname, app.isforreconsideration, app.isforamendment
from
TBWORKFLOWPROCESS pro
left join
TBLSTAPP app on app.applicationtype = pro.workflowid
where
sequenceno >= 10 and pro.workflowid = 1
group by
pro.processname, app.isforreconsideration, app.isforamendment
Output:
processname isforreconsideration isforamendment
------------------------------------------------------------------------
booked
booked,doc pending
cancelled
rejected
The output is correct but what I want is this.
processname
---------------
booked
booked,doc pending
cancelled
rejected
isforreconsideration
isforamendment
Can anyone help me with this? Thanks guys.
Given that the question you asked leaves a lot to be explained, and based on what I could understand and a lot assumptions, I think you want to incorporate the values of the two attributes (isforreconsideration and isforamendment) for the same condition and show them under the attribute of processname.
Hence, here, I am assuming that you need the all the data under one column.
In the code below, I have basically just added two more rows using UNION keyword, and hence the underhanded coding of renaming it as the other column.
select
pro.processname
from
TBWORKFLOWPROCESS pro
LEFT JOIN TBLSTAPP app on app.applicationtype = pro.workflowid
where
pro.sequenceno >=10
and pro.workflowid = 1
union
select
app.isforreconsideration as 'processname'
from
TBWORKFLOWPROCESS pro
LEFT JOIN TBLSTAPP app on app.applicationtype = pro.workflowid
where
sequenceno >=10
and pro.workflowid = 1
union
select app.isforamendment as 'processname'
from
TBWORKFLOWPROCESS pro
LEFT JOIN TBLSTAPP app on app.applicationtype = pro.workflowid
where
sequenceno >=10
and pro.workflowid = 1
P.S. : I am very much sure that this code is not very correct and I may have touched the nerve of one too many, but if you could give the type of data, each column holds and the examples of which kind of data, you want as output, many others would be able to help.

Oracle SQL Return Count of Primary key from 2 different columns in the same table

Tables
ARMASTER = Customer Information
ORDERHEAD = Sales order information (Ship to, bill to)
Hey everyone! I'm still quite new to SQL and I do belive I'm picking it up fairly quick. I have been racking my brain on this for a few hours now and have asked around the office and nobody seems to have a solution.
I'm trying to identify how many times a customer account has been used as a SHIP TO location & a BILL TO location.
SELECT ARMASTER.CUSTOMER,
ARMASTER.DIVISION,
ARMASTER.STATUS,
ARMASTER.CUHEAD AS "MASTER",
COUNT (ORDERHEAD.BILLTO) AS "COUNT_BILL",
COUNT (ORDERHEAD.SHIPTO) AS "COUNT_SHIP"
FROM ARMASTER
LEFT OUTER JOIN ORDERHEAD
ON ARMASTER.CUSTOMER = ORDERHEAD.BILLTO
LEFT OUTER JOIN ORDERHEAD
ON ARMASTER.CUSTOMER = ORDERHEAD.SHIPTO
GROUP BY ARMASTER.CUSTOMER,
ARMASTER.DIVISION,
ARMASTER.STATUS,
ARMASTER.CUHEAD
And I'm not even remotley getting what I should be getting. However, when I remove one of my joins the count is exactly what it should be for either 1 or the other of them.
Any guidance would be muchly appreciated! Thank you!
I think it can also work
SELECT CUSTOMER,
DIVISION,
STATUS,
CUHEAD AS "MASTER",
(SELECT COUNT(1) FROM ORDERHEAD WHERE SHIPTO = ARMASTER.CUSTOMER ) AS "COUNT_BILL",
(SELECT COUNT(1) FROM ORDERHEAD WHERE BILLTO = ARMASTER.CUSTOMER ) AS "COUNT_SHIP"
FROM ARMASTER

T-SQL JOIN Table On Self Based on Closest Date

Thank you in advance for reading!
The question I'm trying to answer is: "How much do parts really cost to make?" We manufacture by machining raw metal billets down to metal parts. Final parts are sold to a customer and scrap metal from the process is sold to the scrap yard.
For business/ERP configuration reasons our scrap vendor is listed as a customer and we ship him 'parts' like our other customers. These dummy parts are simply for each of the metal alloys we work with, so there is one dummy scrap part for each alloy we use. The scrap shipments are made whenever we fill our scrap bins so there's no defined time interval.
I'm trying to connect the ship date of a real part to a real customer to the closest scrap ship date of the same alloy. Then I can grab the scrap value per pound we were paid and include it in our revenue for the parts we make. If I can ask for the world it would be helpful to know how to grab the scrap shipment immediately before or immediately after the shipment of a real part - I'm sure management will change their minds several times debating if they want to use the 'before' or 'after' number.
I've tried other solutions and can't get them to work. I'm crying uncle, I simply can't get it to work....the web SQL interface our ERP uses claims it's T-SQL... thank you for reading this far!
What I'd like the output to look like is:
Customer Part Price Alloy Weight_Lost Scrap_Value Ship_Date
ABC Widget1 99.99 C182 63 2.45 10-01-2016
Here's the simplest I can boil the tables down to:
SELECT
tbl_Regular_Sales.Customer
tbl_Regular_Sales.Part
tbl_Regular_Sales.Price
tbl_Regular_Sales.Alloy
tbl_Regular_Sales.Weight_Lost
tbl_Scrap_Sales.Price AS 'Scrap_Value'
tbl_Regular_Sales.Ship_Date
FROM
(SELECT P.Part
,P.Alloy
,P.Price
,S.Ship_Date
,S.Customer
FROM Part AS P
JOIN S AS S
ON S.Part_Key = P.Part_Key
WHERE Shipper.Customer = 'Scrap_Yard'
) AS tbl_Scrap_Sales
JOIN
(SELECT P.Part
,P.Weight_Lost
,P.Alloy
,P.Price
,S.Ship_Date
,S.Customer
FROM Part AS P
JOIN S AS S
ON S.Part_Key = P.Part_Key
WHERE Shipper.Customer <> 'Scrap_Yard' ) AS tbl_Regular_Sales
ON
tbl_Regular_Sales.Alloy = tbl_Scrap_Sales.Alloy
AND <Some kind of date JOIN to get the closest scrap shipment value>
Something like this may do the trick:
WITH cteScrapSales AS (
SELECT
P.Alloy
,P.Price
,S.Ship_Date
FROM Part AS P
JOIN Shipper AS S ON S.Part_Key = P.Part_Key
WHERE S.Customer = 'Scrap_Yard'
), cteRegularSales AS (
SELECT
P.Part_Key
,P.Part
,P.Weight_Lost
,P.Alloy
,P.Price
,S.Ship_Date
,S.Customer
FROM Part AS P
JOIN Shipper AS S ON S.Part_Key = P.Part_Key
WHERE S.Customer <> 'Scrap_Yard'
)
SELECT
C.Customer
,C.Part
,C.Price
,C.Alloy
,C.Weight_Lost
,C.Scrap_Value
,C.Ship_Date
FROM (
SELECT R.*, S.Price AS Scrap_Value, ROW_NUMBER() OVER (PARTITION BY R.Part_Key ORDER BY DATEDIFF(SECOND, R.Ship_Date, S.Ship_Date)) ix
FROM cteRegularSales R
JOIN cteScrapSales S ON S.Allow = R.Allow AND S.Ship_Date > R.Ship_Date
) AS C
WHERE C.ix = 1;

Access data source using SQL to show most recent entry per site

First of all I am a complete beginner to SQL and have been thrown in at the deep end a bit ! I'm learning as I go along and each mistake I make or question I ask will hopefully help me develop... please be kind :)
I have a working query that extracts electricty meter readings and other information. I am after finding the most recent reading for each site. This is the query at the moment :
PARAMETERS [Site Group] Text ( 255 );
SELECT
Lookup.Lookup_Name AS [Group],
Contacts.Name AS Site,
Points.Number AS MPAN,
Max(DataElectricity.Date) AS MaxDate,
DataElectricity.M1_Present,
DataElectricity.M2_Present,
DataElectricity.M3_Present,
DataElectricity.M4_Present,
DataElectricity.M5_Present,
DataElectricity.M6_Present,
DataElectricity.M7_Present,
DataElectricity.M8_Present,
DataElectricity.Direct
FROM
DataElectricity INNER JOIN (Lookup INNER JOIN (Points INNER JOIN Contacts ON Points.Contacts_Id = Contacts.Id) ON Lookup.Lookup_Id = Contacts.Group_1) ON DataElectricity.Point_Id = Points.Id
WHERE
((DataElectricity.Direct)='D')
GROUP BY
Lookup.Lookup_Name, Contacts.Name, Points.Number, DataElectricity.M1_Present, DataElectricity.M2_Present, DataElectricity.M3_Present, DataElectricity.M4_Present, DataElectricity.M5_Present, DataElectricity.M6_Present, DataElectricity.M7_Present, DataElectricity.M8_Present, DataElectricity.Direct
ORDER BY
Lookup.Lookup_Name, Contacts.Name, Max(DataElectricity.Date) DESC;
However this returns all the readings for a site rather than just the most recent... I'm sure this is simple but I can't figure it out.
Any advice or guidence is gratefully received :)
Can't you just use top 1 to get only the first result?
SELECT top 1 ...
I have evolved the code a bit further using caspian's suggestion of SELECT top 1... but am struggling to refine it further and produce the result I need.
PARAMETERS [Site Group] Text ( 255 );
SELECT
Lookup.Lookup_Name,
Contacts.Name AS Site,
Points.Number AS MPAN,
DataElectricity.M1_Present,
DataElectricity.M2_Present,
DataElectricity.M3_Present,
DataElectricity.M4_Present,
DataElectricity.M5_Present,
DataElectricity.M6_Present,
DataElectricity.M7_Present,
DataElectricity.M8_Present,
DataElectricity.Direct
FROM
(
SELECT TOP 1 DataElectricity.Date AS MaxDate,
DataElectricity.M1_Present,
DataElectricity.M2_Present,
DataElectricity.M3_Present,
DataElectricity.M4_Present,
DataElectricity.M5_Present,
DataElectricity.M6_Present,
DataElectricity.M7_Present,
DataElectricity.M8_Present,
DataElectricity.Point_id
FROM
DataElectricity
ORDER BY MaxDate DESC
)
DataElectricity INNER JOIN (Lookup INNER JOIN (Points INNER JOIN Contacts ON Points.Contacts_Id = Contacts.Id) ON Lookup.Lookup_Id = Contacts.Group_1) ON DataElectricity.Point_Id = Points.Id
WHERE
((Lookup.Lookup_Name)=Lookup_Name)
ORDER BY
Lookup.Lookup_Name, Contacts.Name, MaxDate DESC;
I do have a Google Drive file showing a small example of the data tables and desired result with hopfully a clear guide as to how the tables connect.
https://docs.google.com/file/d/0BybrcUCD29TxWVRsV1VtTm1Bems/edit?usp=sharing
The actual data contains hundreds of Site Groups each with potentially hundreds of sites.
I would like my end users to be able to select the Site Group name from the Lookup.Lookup_Name list and for it to return all the relevant sites and readings.
.... I really hope that makes sense !