ORACLE - check if time is in between two timestamp - oracle

I have a simple query which will return either A or B depending on the projected oven out date and time. If the projected oven out date and time is between 6am and 6pm, A should be returned. Otherwise B if time is between 6pm and 6am of the next day. My problem is that I do not know how to display A or B depending on the projected oven out date and time. I am using the query below to get the projected oven out date and time.
SELECT DISTINCT
to_char((ti.txndate + pm.baketime/24),'MM/DD/YYYY HH:MI:SS PM') FCSTDOvenOut
FROM CONTAINER c
JOIN movin movin ON c.containerid = movin.historyid
JOIN product p ON c.productid = p.productid AND p.attr_016 IN ('TEST', 'TR')
JOIN productbase pb ON p.productbaseid = pb.productbaseid
LEFT JOIN otherdb.pkg_main pm ON TRIM(p.brandname) = TRIM(pm.pcode)
LEFT JOIN employee e ON movin.employeeid = e.employeeid
JOIN trackin ti ON c.containerid = ti.historyid AND ti.txndate > movin.txndate
LEFT JOIN employee em ON ti.employeeid = em.employeeid
;
Example:
Thanks for helping everyone.

SELECT DISTINCT
case when
to_char(ti.txndate + pm.baketime/24,'hh24') between '06' and '17' then 'A'
else 'B'
end shift,
....

Related

join three tables with count and sum in oracle

I have three tables and trying to join these tables with count(working_days) and sum(Overtime) functions but overtime is not showing correct i am trying the query is.
SELECT E.EMP_CODE,E.EMP_NAME,
COALESCE(SUM(O.OVERTIME),0) AS OVERTIME,COALESCE(COUNT(C.EMP_ATT),0) WORKED_DAYS
FROM EMP E
LEFT JOIN OVERTIME O
ON E.EMP_CODE = O.EMP_CODE
LEFT JOIN ATT_REG C
ON E.EMP_CODE=C.EMP_CODE
GROUP BY E.EMP_CODE,E.EMP_NAME
ORDER BY EMP_CODE
Yes, You will get multiple records of the overtime for employees as shift date (or similar in your table) is missing in the join.
SELECT E.EMP_CODE,E.EMP_NAME,
COALESCE(SUM(O.OVERTIME),0) AS OVERTIME,
COALESCE(COUNT(C.EMP_ATT),0) WORKED_DAYS
FROM EMP E
LEFT JOIN ATT_REG C
ON E.EMP_CODE=C.EMP_CODE
LEFT JOIN OVERTIME O
ON E.EMP_CODE = O.EMP_CODE
AND C.SHIFTDATE = O.SHIFDATE -- YOU NEED SOMETHING LIKE THIS
GROUP BY E.EMP_CODE,E.EMP_NAME
ORDER BY EMP_CODE

speed up a query with multiple inner joins in ms access

as tittle says i need to improve this query that i have made in ms access, the tables are from a linked DB. i can't index them. i need help to understand where it is taking so long... is there any function like
EXPLAIN to access? do i need to put more columns in some sort of group by? what i need to do to improve the speed of this (the group by of first select has 4M rows but after grouped only has 321k and it takes 20min to run when laptop doesn't crashes)
SELECT a.SEQ_NO,
b.SKU,
b.maxdate,
(a.BASE_COST/a.EXCHANGE) AS BASE_COST,
(a.NET_COST/a.EXCHANGE) AS NET_COST,
(a.NET_NET_COST/a.EXCHANGE) AS EXCHAGED_NET_NET_COST,
a.NET_NET_COST,
(a.DEAD_NET_NET_COST/a.EXCHANGE) AS DEAD_NET_NET_COST,
(a.LANDED_COST/a.EXCHANGE) AS LANDED_COST,
(a.POSEIMA/a.EXCHANGE) AS POSEIMA,
(a.TOTAL_BONUS/a.EXCHANGE) AS TOTAL_BONUS,
(a.IEC/a.EXCHANGE) AS IEC,
(a.IEC_BONUS/a.EXCHANGE) AS IEC_BONUS,
(a.ECO_INVOICE_FORN/a.EXCHANGE) AS ECO_INVOICE_FORN_SYSTEM,
(a.ECO_INVOICE/a.EXCHANGE) AS ECO_INVOICE_SYSTEM,
(a.ECO_MERCHANDISE/a.EXCHANGE) AS ECO_MERCHANDISE_SYSTEM,
c.SUPPLIER,
c.SUP_NAME,
d.UPC,
d.PRIMARY_UPC_IND,
f.BRAND,
g.DEPT,
g.DESC_UP,
g.CLASS,
g.SUBCLASS,
h.AV_COST,
h.UNIT_RETAIL AS Last_of_unit_retail,
h.STATUS, i.[UNIT VALUE],
i.[INITIAL DATE],
i.[END DATE] INTO PRICELIST
FROM (((((((RMS_MC_NB_PRICELIST_COST AS a INNER JOIN (SELECT MAX(SEQ_NO) AS
ID, SKU, MAX(ACTIVE_DATE) AS maxdate FROM RMS_MC_NB_PRICELIST_COST GROUP BY
SKU) AS b ON a.SEQ_NO = b.ID)
INNER JOIN RMS_MC_SUPS AS c ON a.SUPPLIER = c.SUPPLIER)
INNER JOIN RMS_MC_UPC_EAN AS d ON b.SKU = d.SKU)
INNER JOIN RMS_MC_WIN_ATTRIBUTES AS e ON b.SKU = e.SKU)
INNER JOIN RMS_MC_NB_BRAND AS f ON e.NB_BRAND_NO = f.BRAND_NO)
INNER JOIN RMS_MC_DESC_LOOK AS g ON b.SKU = g.SKU)
INNER JOIN RMS_MC_WIN_STORE AS h ON b.SKU = h.SKU)
LEFT JOIN MAPA_APOIOS_SISO AS i ON b.SKU = i.[# ARTICLE];

Oracle CONNECT BY and MAX

I am having difficulty integrating a MAX into a query and would greatly appreciate any help.
Basically what I'm trying to achieve is this: list a supervisor's supervisor's supervised employees along with their latest "day out" punch time.
The part I can't get right is the MAX(day out) part.
Here's the part I got so far that works fine:
SELECT EMPLOYEE.NUMBER,
EMPLOYEE.NAME,
S.NAME AS SUPERVISOR,
EMPLOYEE.HIRE_DATE
FROM EMPLOYEE
LEFT JOIN EMPLOYEE_NUMBER ON EMPLOYEE_NUMBER.NUMBER = EMPLOYEE.SUPERVISOR_NUMBER
LEFT JOIN EMPLOYEE S ON S.NUMBER = EMPLOYEE.SUPERVISOR_NUMBER
WHERE LEVEL =2
START WITH EMPLOYEE_NUMBER.USERID = (ID OF SUPERVISOR HERE)
CONNECT BY PRIOR EMPLOYEE.NUMBER = EMPLOYEE.SUPERVISOR_NUMBER
This part works and gives me the basic input that I need. However, I also need to list, for each employee, his/her lastest "day out" date.
Here's what I tried tried that didn't work:
SELECT EMPLOYEE.NUMBER,
EMPLOYEE.NAME,
S.NAME AS SUPERVISOR,
EMPLOYEE.HIRE_DATE,
MAX(EMPLOYEE_TIME.DATE_OUT)
FROM EMPLOYEE
LEFT JOIN EMPLOYEE_NUMBER ON EMPLOYEE_NUMBER.NUMBER = EMPLOYEE.SUPERVISOR_NUMBER
LEFT JOIN EMPLOYEE S ON S.NUMBER = EMPLOYEE.SUPERVISOR_NUMBER
LEFT JOIN EMPLOYEE_TIME ON EMPLOYEE_TIME.EMPLOYEE_NUMBER = EMPLOYEE.EMPLOYEE_NUMBER
WHERE LEVEL =2
START WITH EMPLOYEE_NUMBER.USERID = (ID OF SUPERVISOR HERE)
CONNECT BY PRIOR EMPLOYEE.NUMBER = EMPLOYEE.SUPERVISOR_NUMBER
GROUP BY
EMPLOYEE.NUMBER,
EMPLOYEE.NAME,
S.NAME,
EMPLOYEE.HIRE_DATE
HAVING MAX(EMPLOYEE_TIME.DATE_OUT) >= SYSDATE-60
It doesn't throw any error, it just keeps on processing forever. I'm guessing something must be looping but I can't figure it out.
Thanks for any help.
A slight change to your query in joining the time table, it need not be joined while CONNECT BY, instead separate it.
SELECT NUMBER,
EMPLOYEE_NAME,
SUPERVISOR,
HIRE_DATE,
MAX(TIME.DATE_OUT)
FROM
(SELECT NUMBER,
EMPLOYEE.NAME AS EMPLOYEE_NAME,
S.NAME AS SUPERVISOR,
EMPLOYEE.HIRE_DATE
FROM EMPLOYEE
LEFT JOIN EMPLOYEE_NUMBER ON EMPLOYEE_NUMBER.NUMBER = EMPLOYEE.SUPERVISOR_NUMBER
LEFT JOIN EMPLOYEE S ON S.NUMBER = EMPLOYEE.SUPERVISOR_NUMBER
WHERE LEVEL =2
START WITH EMPLOYEE_NUMBER.USERID = (ID OF SUPERVISOR HERE)
CONNECT BY PRIOR EMPLOYEE.NUMBER = EMPLOYEE.SUPERVISOR_NUMBER) EMP_SUP
INNER JOIN EMPLOYEE_TIME TIME
ON( EMP_SUP.NUMBER = TIME.NUMBER)
GROUP BY
NUMBER,
EMPLOYEE_NAME,
SUPERVISOR,
HIRE_DATE
HAVING MAX(DATE_OUT) >= SYSDATE-60

Counting the total number of rows depending on a column value

I have a query that should count the total number of rows returned depending on a column value. For example:
As you can see, the M field should display the total number of rows returned which should be 5 because the FT_LOT are all the same value. Here is the query that I have so far:
SELECT DISTINCT
VBATCH_ID, MAXIM_PN, BAGNUMBER, FT_LOT
, m
, level as n
FROM
(
SELECT
VBATCH_ID, MAXIM_PN, BAGNUMBER, FT_LOT, QTY, DC, PRINTDATE, WS_GREEN, WS_PNR, WS_PCN, MSL, BAKETIME, EXPTIME
, una
, dulo
, (dulo - una) + 1 AS m
FROM
(
SELECT c.containername VBATCH_ID
,pb.productname MAXIM_PN
,bn.wipdatavalue BAGNUMBER
,ln.wipdatavalue FT_LOT
,aw.wipdatavalue QTY
,DECODE(ln.wipdatavalue,la.attr_081,la.attr_083
,la.attr_085,la.attr_087
,la.attr_089,la.attr_091
,la.attr_093,la.attr_095
,la.attr_097,la.attr_099
,la.attr_101,la.attr_103
,la.attr_105,la.attr_107
,la.attr_109,la.attr_111
,la.attr_113,la.attr_116
,la.attr_117,la.attr_119
) DC
,TO_CHAR(SYSDATE,'MM/DD/YYYY HH:MI:SS PM') PRINTDATE
,DECODE(UPPER(la.attr_158),'GREEN','HF',NULL) WS_GREEN
,DECODE(la.attr_140,NULL,NULL,'PNR') WS_PNR
,DECODE(la.Attr_080,NULL,NULL,'PCN') WS_PCN
,p.attr_011 MSL
,P.attr_013 BAKETIME
,p.attr_014 EXPTIME
, CASE
WHEN INSTR(bn.wipdatavalue, '-') = 0 THEN
bn.wipdatavalue
ELSE
SUBSTR(bn.wipdatavalue, 1, INSTR(bn.wipdatavalue, '-')-1)
END AS una
, CASE
WHEN INSTR(bn.wipdatavalue, '-') = 0 THEN
bn.wipdatavalue
ELSE
SUBSTR(bn.wipdatavalue, INSTR(bn.wipdatavalue, '-') + 1)
END AS dulo
FROM Container C
JOIN a_lotattributes la ON c.lotattributesid = la.lotattributesid
JOIN product p ON c.productid=p.productid
JOIN productbase pb ON p.productbaseid=pb.productbaseid
JOIN a_adhocwipdatarecord a ON a.objectrefid=c.containerid
JOIN a_adhocwipdatarecorddetails bn ON a.adhocwipdatarecordid=bn.adhocwipdatarecordid AND bn.wipdatanamename ='TR_BAG_NUMBER'
LEFT JOIN a_adhocwipdatarecorddetails ln ON a.adhocwipdatarecordid=ln.adhocwipdatarecordid AND ln.wipdatanamename ='TR_FT_LOT NUMBER'
LEFT JOIN a_adhocwipdatarecorddetails aw ON A.adhocwipdatarecordid=aw.adhocwipdatarecordid AND aw.wipdatanamename ='TR_FT LOT QTY'
WHERE ln.wipdatavalue = :ftlot AND bn.wipdatavalue LIKE :wip
)
) WHERE level LIKE :n
CONNECT BY LEVEL <= m
ORDER BY BAGNUMBER
Thanks for helping out guys.
Actually GROUP BY is not the solution. Having looked again at your desired output I have realised that what you want is an analytic count.
Your posted query is a bit of a mess and, sorry ,but I'm not prepared to invest time in it. This is the sort of structure you need:
select vbatch_id, maxim_pn, bagnumber, ft_lot
, count(*) over (partition by ft_lot) m
from whatever ...
Find out more.
Not sure why you need the DISTINCT. DISTINCT almost always indicates a failure to get the WHERE clause right.

Query that uses Clustered Index Scan instead of seek

I have the following query that returns < 300 results. It is currently taking about 4 seconds to complete, and when I look at the execution plan, it shows that it is spending 41% of resources on a clustered index scan. My limited knowledge of database administration suggests that a clustered index seek would improve performance. How can I get the query to use a clustered index seek instead of a clustered index scan? Below is the pertinent information and the query.
Sql Server 2008 R2
Table PMDME approx 140,000 rows (this is the one that is taking up 41% of resources)
Server Hardware: 16 core 2.7gz processors, 48gb ram
DECLARE #start date, #end date
SET #start = '2013-01-01'
SET #end = CAST(GETDATE() AS DATE)
SELECT
b.total,
c.intakes,
d.ships,
a.CODE_,
RTRIM(a.NAME_) as name,
f.employee as Salesperson,
g.referral_type_id,
h.referral_type,
e.slscode,
a.city,
a.STATE_,
a.zip
FROM PACWARE.ADS.RFDME a
LEFT OUTER JOIN (
SELECT SUM(b.quantity) total, a.ref_id from event.dbo.sample a
JOIN event.dbo.sample_parts b on a.id = b.sample_id
JOIN PACWARE.ADS.PTDME c on b.part_id = c.CODE_
WHERE c.MEDICAREID = 'E0607' AND a.order_date between #start and #end
GROUP BY a.ref_id
)b on a.CODE_ = b.ref_id
LEFT OUTER JOIN (
SELECT COUNT(a.CODE_)as intakes, rfcode
FROM PACWARE.ADS.PMDME a
WHERE a.REGDATETIME BETWEEN #start and #end
GROUP BY a.RFCODE
) c on a.CODE_ = c.rfcode
LEFT OUTER JOIN (
SELECT
COUNT(a.CODE) as ships, b.rfcode
FROM
(
SELECT
A.ACCOUNT AS CODE,
MIN(CAST(A.BILLDATETIME AS DATE)) AS SHIPDATE
FROM PACWARE.ADS.ARODME A
LEFT OUTER JOIN PACWARE.ADS.PTDME B ON A.PTCODE=B.CODE_
LEFT OUTER JOIN event.dbo.newdate() D ON A.ACCOUNT=D.ACCOUNT
LEFT OUTER JOIN event.dbo.newdate_extras() D2 ON A.ACCOUNT=D2.ACCOUNT
WHERE A.BILLDATETIME>=#start
AND A.BILLDATETIME=#start AND D.NEWDATE=#start AND D2.NEWDATE'ID'
Group by
A.ACCOUNT,
B.MEDICAREID,
A.CATEGORY
) a
JOIN PACWARE.ADS.PMDME b on a.CODE = b.CODE_
GROUP BY b.RFCODE
) d on a.CODE_ = d.rfcode
LEFT OUTER JOIN event.dbo.employee_slscode e on a.SLSCODE = e.slscode
JOIN event.dbo.employee f on e.employee_id = f.id
JOIN event.dbo.referral_data g on a.CODE_ = g.CODE_
JOIN event.dbo.referral_type h on g.referral_type_id = h.id
WHERE total > 0
I would try creating first and index just for the colum REGDATETIME on PACWARE.ADS.PMDME table.
GO
CREATE NONCLUSTERED INDEX [IX_PMDME_REGDATETIME] ON PACWARE.ADS.PMDME
(
[REGDATETIME] ASC
)
GO
Test how it works. I would also test adding another index to the column RFCODE (same table) if the selectivity of the column is good enough.

Resources