Need help understanding range between in SQL window functions












0














I am trying understand how range clause is working in below case (oracle database)



SELECT
EMPID,NAME,
HIRE_DATE_1,
SALARY,
count(1) over(order by HIRE_DATE_1 range between 1 preceding and 1 preceding) as PREV_MIN_SA
FROM (
SELECT
EMPID,
NAME,
(EXTRACT(year from HIRE_DATE)*10000)+(EXTRACT(MONTH FROM HIRE_DATE) * 100) + (extract(DAY from HIRE_DATE)) as HIRE_DATE_1,SALARY
FROM EMPLOYEE A order by HIRE_DATE,SALARY
) A
ORDER BY HIRE_DATE_1


Result Set :



EMPID   NAME    HIRE_DATE_1 SALARY  PREV_MIN_SA
100 Ravi 20180101 5000 0
101 Kumar 20180101 7000 0
102 Satish 20180101 13000 0
103 Naresh 20180102 7500 3
105 Lalith 20180104 17300 0
104 Suresh 20180104 40000 0
106 Latha 20180201 16000 0


The inner query is just converting date into numeric YYYYMMDD format.
My intention is to get the count of people who joined immediately prior to the date of the employee in each record. I can take the count of rows with same HIRE_DATE and use LAG function but somehow not understand how the sql is returning this result set.



Also, once I am done with the counts I would like to get the MIN(SALARY) of the employees who joined immediately prior to the employee in current row and find the difference in salaries so wondering if somehow I can define the window to only have all records with immediately prior HIRE_DATE.



Thanks










share|improve this question
























  • Which dbms are you using?
    – jarlh
    Nov 21 '18 at 15:27










  • Please explain what you are trying to do.
    – Gordon Linoff
    Nov 21 '18 at 15:34










  • That counts the number of rows where the HIRE_DATE_1 is exactly one less than the current row's HIRE_DATE_1. Because you went to the effort of converting the date to an integer, it will "break" on month boundaries and year boundaries. Why did you convert the data to an integer!?
    – MatBailie
    Nov 21 '18 at 15:36












  • I am using Oracle Live SQL (online) so not sure what version it runs at the background
    – zulfi123786
    Nov 21 '18 at 15:38










  • @MatBailie : I was thinking "range with 1 preceding " would refer to the value prior in the ordered set instead of exactly 1 minus. I converted to integer as I was more comfortable with integer arithmetic than deal with timestamps (oracle seems to capture timestamps in date datatypes)
    – zulfi123786
    Nov 21 '18 at 15:42
















0














I am trying understand how range clause is working in below case (oracle database)



SELECT
EMPID,NAME,
HIRE_DATE_1,
SALARY,
count(1) over(order by HIRE_DATE_1 range between 1 preceding and 1 preceding) as PREV_MIN_SA
FROM (
SELECT
EMPID,
NAME,
(EXTRACT(year from HIRE_DATE)*10000)+(EXTRACT(MONTH FROM HIRE_DATE) * 100) + (extract(DAY from HIRE_DATE)) as HIRE_DATE_1,SALARY
FROM EMPLOYEE A order by HIRE_DATE,SALARY
) A
ORDER BY HIRE_DATE_1


Result Set :



EMPID   NAME    HIRE_DATE_1 SALARY  PREV_MIN_SA
100 Ravi 20180101 5000 0
101 Kumar 20180101 7000 0
102 Satish 20180101 13000 0
103 Naresh 20180102 7500 3
105 Lalith 20180104 17300 0
104 Suresh 20180104 40000 0
106 Latha 20180201 16000 0


The inner query is just converting date into numeric YYYYMMDD format.
My intention is to get the count of people who joined immediately prior to the date of the employee in each record. I can take the count of rows with same HIRE_DATE and use LAG function but somehow not understand how the sql is returning this result set.



Also, once I am done with the counts I would like to get the MIN(SALARY) of the employees who joined immediately prior to the employee in current row and find the difference in salaries so wondering if somehow I can define the window to only have all records with immediately prior HIRE_DATE.



Thanks










share|improve this question
























  • Which dbms are you using?
    – jarlh
    Nov 21 '18 at 15:27










  • Please explain what you are trying to do.
    – Gordon Linoff
    Nov 21 '18 at 15:34










  • That counts the number of rows where the HIRE_DATE_1 is exactly one less than the current row's HIRE_DATE_1. Because you went to the effort of converting the date to an integer, it will "break" on month boundaries and year boundaries. Why did you convert the data to an integer!?
    – MatBailie
    Nov 21 '18 at 15:36












  • I am using Oracle Live SQL (online) so not sure what version it runs at the background
    – zulfi123786
    Nov 21 '18 at 15:38










  • @MatBailie : I was thinking "range with 1 preceding " would refer to the value prior in the ordered set instead of exactly 1 minus. I converted to integer as I was more comfortable with integer arithmetic than deal with timestamps (oracle seems to capture timestamps in date datatypes)
    – zulfi123786
    Nov 21 '18 at 15:42














0












0








0







I am trying understand how range clause is working in below case (oracle database)



SELECT
EMPID,NAME,
HIRE_DATE_1,
SALARY,
count(1) over(order by HIRE_DATE_1 range between 1 preceding and 1 preceding) as PREV_MIN_SA
FROM (
SELECT
EMPID,
NAME,
(EXTRACT(year from HIRE_DATE)*10000)+(EXTRACT(MONTH FROM HIRE_DATE) * 100) + (extract(DAY from HIRE_DATE)) as HIRE_DATE_1,SALARY
FROM EMPLOYEE A order by HIRE_DATE,SALARY
) A
ORDER BY HIRE_DATE_1


Result Set :



EMPID   NAME    HIRE_DATE_1 SALARY  PREV_MIN_SA
100 Ravi 20180101 5000 0
101 Kumar 20180101 7000 0
102 Satish 20180101 13000 0
103 Naresh 20180102 7500 3
105 Lalith 20180104 17300 0
104 Suresh 20180104 40000 0
106 Latha 20180201 16000 0


The inner query is just converting date into numeric YYYYMMDD format.
My intention is to get the count of people who joined immediately prior to the date of the employee in each record. I can take the count of rows with same HIRE_DATE and use LAG function but somehow not understand how the sql is returning this result set.



Also, once I am done with the counts I would like to get the MIN(SALARY) of the employees who joined immediately prior to the employee in current row and find the difference in salaries so wondering if somehow I can define the window to only have all records with immediately prior HIRE_DATE.



Thanks










share|improve this question















I am trying understand how range clause is working in below case (oracle database)



SELECT
EMPID,NAME,
HIRE_DATE_1,
SALARY,
count(1) over(order by HIRE_DATE_1 range between 1 preceding and 1 preceding) as PREV_MIN_SA
FROM (
SELECT
EMPID,
NAME,
(EXTRACT(year from HIRE_DATE)*10000)+(EXTRACT(MONTH FROM HIRE_DATE) * 100) + (extract(DAY from HIRE_DATE)) as HIRE_DATE_1,SALARY
FROM EMPLOYEE A order by HIRE_DATE,SALARY
) A
ORDER BY HIRE_DATE_1


Result Set :



EMPID   NAME    HIRE_DATE_1 SALARY  PREV_MIN_SA
100 Ravi 20180101 5000 0
101 Kumar 20180101 7000 0
102 Satish 20180101 13000 0
103 Naresh 20180102 7500 3
105 Lalith 20180104 17300 0
104 Suresh 20180104 40000 0
106 Latha 20180201 16000 0


The inner query is just converting date into numeric YYYYMMDD format.
My intention is to get the count of people who joined immediately prior to the date of the employee in each record. I can take the count of rows with same HIRE_DATE and use LAG function but somehow not understand how the sql is returning this result set.



Also, once I am done with the counts I would like to get the MIN(SALARY) of the employees who joined immediately prior to the employee in current row and find the difference in salaries so wondering if somehow I can define the window to only have all records with immediately prior HIRE_DATE.



Thanks







sql oracle sql-order-by window-functions






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 '18 at 15:55









David Marabottini

1707




1707










asked Nov 21 '18 at 15:25









zulfi123786

2615




2615












  • Which dbms are you using?
    – jarlh
    Nov 21 '18 at 15:27










  • Please explain what you are trying to do.
    – Gordon Linoff
    Nov 21 '18 at 15:34










  • That counts the number of rows where the HIRE_DATE_1 is exactly one less than the current row's HIRE_DATE_1. Because you went to the effort of converting the date to an integer, it will "break" on month boundaries and year boundaries. Why did you convert the data to an integer!?
    – MatBailie
    Nov 21 '18 at 15:36












  • I am using Oracle Live SQL (online) so not sure what version it runs at the background
    – zulfi123786
    Nov 21 '18 at 15:38










  • @MatBailie : I was thinking "range with 1 preceding " would refer to the value prior in the ordered set instead of exactly 1 minus. I converted to integer as I was more comfortable with integer arithmetic than deal with timestamps (oracle seems to capture timestamps in date datatypes)
    – zulfi123786
    Nov 21 '18 at 15:42


















  • Which dbms are you using?
    – jarlh
    Nov 21 '18 at 15:27










  • Please explain what you are trying to do.
    – Gordon Linoff
    Nov 21 '18 at 15:34










  • That counts the number of rows where the HIRE_DATE_1 is exactly one less than the current row's HIRE_DATE_1. Because you went to the effort of converting the date to an integer, it will "break" on month boundaries and year boundaries. Why did you convert the data to an integer!?
    – MatBailie
    Nov 21 '18 at 15:36












  • I am using Oracle Live SQL (online) so not sure what version it runs at the background
    – zulfi123786
    Nov 21 '18 at 15:38










  • @MatBailie : I was thinking "range with 1 preceding " would refer to the value prior in the ordered set instead of exactly 1 minus. I converted to integer as I was more comfortable with integer arithmetic than deal with timestamps (oracle seems to capture timestamps in date datatypes)
    – zulfi123786
    Nov 21 '18 at 15:42
















Which dbms are you using?
– jarlh
Nov 21 '18 at 15:27




Which dbms are you using?
– jarlh
Nov 21 '18 at 15:27












Please explain what you are trying to do.
– Gordon Linoff
Nov 21 '18 at 15:34




Please explain what you are trying to do.
– Gordon Linoff
Nov 21 '18 at 15:34












That counts the number of rows where the HIRE_DATE_1 is exactly one less than the current row's HIRE_DATE_1. Because you went to the effort of converting the date to an integer, it will "break" on month boundaries and year boundaries. Why did you convert the data to an integer!?
– MatBailie
Nov 21 '18 at 15:36






That counts the number of rows where the HIRE_DATE_1 is exactly one less than the current row's HIRE_DATE_1. Because you went to the effort of converting the date to an integer, it will "break" on month boundaries and year boundaries. Why did you convert the data to an integer!?
– MatBailie
Nov 21 '18 at 15:36














I am using Oracle Live SQL (online) so not sure what version it runs at the background
– zulfi123786
Nov 21 '18 at 15:38




I am using Oracle Live SQL (online) so not sure what version it runs at the background
– zulfi123786
Nov 21 '18 at 15:38












@MatBailie : I was thinking "range with 1 preceding " would refer to the value prior in the ordered set instead of exactly 1 minus. I converted to integer as I was more comfortable with integer arithmetic than deal with timestamps (oracle seems to capture timestamps in date datatypes)
– zulfi123786
Nov 21 '18 at 15:42




@MatBailie : I was thinking "range with 1 preceding " would refer to the value prior in the ordered set instead of exactly 1 minus. I converted to integer as I was more comfortable with integer arithmetic than deal with timestamps (oracle seems to capture timestamps in date datatypes)
– zulfi123786
Nov 21 '18 at 15:42












2 Answers
2






active

oldest

votes


















0














This should get the preceding hire date...



SELECT
EMPID,NAME, HIRE_DATE, SALARY,
MAX(HIRE_DATE) OVER (ORDER BY HIRE_DATE
RANGE BETWEEN UNBOUNDED PRECEDING
AND INTERVAL '1 DAY' PRECEDING
)
AS PREV_HIRE_DATE
FROM
EMPLOYEE


Then I think you need to join back on to the employee table to find the number of employees and their min salary?



SELECT
*
FROM
(
SELECT
EMPID,NAME, HIRE_DATE, SALARY,
MAX(HIRE_DATE) OVER (ORDER BY HIRE_DATE
RANGE BETWEEN UNBOUNDED PRECEDING
AND INTERVAL '1 DAY' PRECEDING
)
AS PREV_HIRE_DATE
FROM
EMPLOYEE
)
EMPS
LEFT JOIN
(
SELECT
HIRE_DATE,
COUNT(*) AS COUNT_EMPS,
MIN(SALARY) AS MIN_SALARY
FROM
EMPLOYEE
GROUP BY
HIRE_DATE
)
PREV_EMPS
ON PREV_EMPS.HIRE_DATE = EMPS.PREV_HIRE_DATE


EDIT:



Maybe try something like this? (I have to run, good luck!)



WITH
ranked AS
(
SELECT
*,
DENSE_RANK() OVER (ORDER BY HIRE_DATE) AS HIRE_SEQ_ID
FROM
EMPLOYEE
)
SELECT
*,
MIN(SALARY) OVER (ORDER BY HIRE_SEQ_ID
RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING
)
AS PREV_MIN_SALARY,
COUNT(*) OVER (ORDER BY HIRE_SEQ_ID
RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING
)
AS COUNT_PREV_EMPS
FROM
ranked





share|improve this answer























  • @zulfi123786 Any luck?
    – MatBailie
    Nov 22 '18 at 9:22



















0














This does what you're after, I believe (I've left it as an exercise for you to find the difference between the max and min salaries!):



WITH employee AS (SELECT 100 empid, 'Ravi' NAME, to_date('01/01/2018', 'dd/mm/yyyy') hire_date, 5000 salary FROM dual UNION ALL
SELECT 101 empid, 'Kumar' NAME, to_date('01/01/2018', 'dd/mm/yyyy') hire_date, 7000 salary FROM dual UNION ALL
SELECT 102 empid, 'Satish' NAME, to_date('01/01/2018', 'dd/mm/yyyy') hire_date, 13000 salary FROM dual UNION ALL
SELECT 103 empid, 'Naresh' NAME, to_date('02/01/2018', 'dd/mm/yyyy') hire_date, 7500 salary FROM dual UNION ALL
SELECT 104 empid, 'Lalith' NAME, to_date('04/01/2018', 'dd/mm/yyyy') hire_date, 17300 salary FROM dual UNION ALL
SELECT 105 empid, 'Suresh' NAME, to_date('04/01/2018', 'dd/mm/yyyy') hire_date, 40000 salary FROM dual UNION ALL
SELECT 106 empid, 'Latha' NAME, to_date('01/02/2018', 'dd/mm/yyyy') hire_date, 16000 salary FROM dual)
SELECT empid,
NAME,
hire_date,
salary,
COUNT(*) OVER (ORDER BY hire_date RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING) prev_day_hire_count,
MIN(salary) OVER (ORDER BY hire_date RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING) prev_day_min_sal,
MAX(salary) OVER (ORDER BY hire_date RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING) prev_day_max_sal
FROM employee;

EMPID NAME HIRE_DATE SALARY PREV_DAY_HIRE_COUNT PREV_DAY_MIN_SAL PREV_DAY_MAX_SAL
---------- ------ ----------- ---------- ------------------- ---------------- ----------------
100 Ravi 01/01/2018 5000 0
101 Kumar 01/01/2018 7000 0
102 Satish 01/01/2018 13000 0
103 Naresh 02/01/2018 7500 3 5000 13000
104 Lalith 04/01/2018 17300 0
105 Suresh 04/01/2018 40000 0
106 Latha 01/02/2018 16000 0





share|improve this answer





















  • The row with EMPID 104 should get PREV_DAY_MIN_SAL=7500. For this record the prior date is '02/01/2018' and there is only one record so consider 7500.
    – zulfi123786
    Nov 21 '18 at 16:36











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53415289%2fneed-help-understanding-range-between-in-sql-window-functions%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














This should get the preceding hire date...



SELECT
EMPID,NAME, HIRE_DATE, SALARY,
MAX(HIRE_DATE) OVER (ORDER BY HIRE_DATE
RANGE BETWEEN UNBOUNDED PRECEDING
AND INTERVAL '1 DAY' PRECEDING
)
AS PREV_HIRE_DATE
FROM
EMPLOYEE


Then I think you need to join back on to the employee table to find the number of employees and their min salary?



SELECT
*
FROM
(
SELECT
EMPID,NAME, HIRE_DATE, SALARY,
MAX(HIRE_DATE) OVER (ORDER BY HIRE_DATE
RANGE BETWEEN UNBOUNDED PRECEDING
AND INTERVAL '1 DAY' PRECEDING
)
AS PREV_HIRE_DATE
FROM
EMPLOYEE
)
EMPS
LEFT JOIN
(
SELECT
HIRE_DATE,
COUNT(*) AS COUNT_EMPS,
MIN(SALARY) AS MIN_SALARY
FROM
EMPLOYEE
GROUP BY
HIRE_DATE
)
PREV_EMPS
ON PREV_EMPS.HIRE_DATE = EMPS.PREV_HIRE_DATE


EDIT:



Maybe try something like this? (I have to run, good luck!)



WITH
ranked AS
(
SELECT
*,
DENSE_RANK() OVER (ORDER BY HIRE_DATE) AS HIRE_SEQ_ID
FROM
EMPLOYEE
)
SELECT
*,
MIN(SALARY) OVER (ORDER BY HIRE_SEQ_ID
RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING
)
AS PREV_MIN_SALARY,
COUNT(*) OVER (ORDER BY HIRE_SEQ_ID
RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING
)
AS COUNT_PREV_EMPS
FROM
ranked





share|improve this answer























  • @zulfi123786 Any luck?
    – MatBailie
    Nov 22 '18 at 9:22
















0














This should get the preceding hire date...



SELECT
EMPID,NAME, HIRE_DATE, SALARY,
MAX(HIRE_DATE) OVER (ORDER BY HIRE_DATE
RANGE BETWEEN UNBOUNDED PRECEDING
AND INTERVAL '1 DAY' PRECEDING
)
AS PREV_HIRE_DATE
FROM
EMPLOYEE


Then I think you need to join back on to the employee table to find the number of employees and their min salary?



SELECT
*
FROM
(
SELECT
EMPID,NAME, HIRE_DATE, SALARY,
MAX(HIRE_DATE) OVER (ORDER BY HIRE_DATE
RANGE BETWEEN UNBOUNDED PRECEDING
AND INTERVAL '1 DAY' PRECEDING
)
AS PREV_HIRE_DATE
FROM
EMPLOYEE
)
EMPS
LEFT JOIN
(
SELECT
HIRE_DATE,
COUNT(*) AS COUNT_EMPS,
MIN(SALARY) AS MIN_SALARY
FROM
EMPLOYEE
GROUP BY
HIRE_DATE
)
PREV_EMPS
ON PREV_EMPS.HIRE_DATE = EMPS.PREV_HIRE_DATE


EDIT:



Maybe try something like this? (I have to run, good luck!)



WITH
ranked AS
(
SELECT
*,
DENSE_RANK() OVER (ORDER BY HIRE_DATE) AS HIRE_SEQ_ID
FROM
EMPLOYEE
)
SELECT
*,
MIN(SALARY) OVER (ORDER BY HIRE_SEQ_ID
RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING
)
AS PREV_MIN_SALARY,
COUNT(*) OVER (ORDER BY HIRE_SEQ_ID
RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING
)
AS COUNT_PREV_EMPS
FROM
ranked





share|improve this answer























  • @zulfi123786 Any luck?
    – MatBailie
    Nov 22 '18 at 9:22














0












0








0






This should get the preceding hire date...



SELECT
EMPID,NAME, HIRE_DATE, SALARY,
MAX(HIRE_DATE) OVER (ORDER BY HIRE_DATE
RANGE BETWEEN UNBOUNDED PRECEDING
AND INTERVAL '1 DAY' PRECEDING
)
AS PREV_HIRE_DATE
FROM
EMPLOYEE


Then I think you need to join back on to the employee table to find the number of employees and their min salary?



SELECT
*
FROM
(
SELECT
EMPID,NAME, HIRE_DATE, SALARY,
MAX(HIRE_DATE) OVER (ORDER BY HIRE_DATE
RANGE BETWEEN UNBOUNDED PRECEDING
AND INTERVAL '1 DAY' PRECEDING
)
AS PREV_HIRE_DATE
FROM
EMPLOYEE
)
EMPS
LEFT JOIN
(
SELECT
HIRE_DATE,
COUNT(*) AS COUNT_EMPS,
MIN(SALARY) AS MIN_SALARY
FROM
EMPLOYEE
GROUP BY
HIRE_DATE
)
PREV_EMPS
ON PREV_EMPS.HIRE_DATE = EMPS.PREV_HIRE_DATE


EDIT:



Maybe try something like this? (I have to run, good luck!)



WITH
ranked AS
(
SELECT
*,
DENSE_RANK() OVER (ORDER BY HIRE_DATE) AS HIRE_SEQ_ID
FROM
EMPLOYEE
)
SELECT
*,
MIN(SALARY) OVER (ORDER BY HIRE_SEQ_ID
RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING
)
AS PREV_MIN_SALARY,
COUNT(*) OVER (ORDER BY HIRE_SEQ_ID
RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING
)
AS COUNT_PREV_EMPS
FROM
ranked





share|improve this answer














This should get the preceding hire date...



SELECT
EMPID,NAME, HIRE_DATE, SALARY,
MAX(HIRE_DATE) OVER (ORDER BY HIRE_DATE
RANGE BETWEEN UNBOUNDED PRECEDING
AND INTERVAL '1 DAY' PRECEDING
)
AS PREV_HIRE_DATE
FROM
EMPLOYEE


Then I think you need to join back on to the employee table to find the number of employees and their min salary?



SELECT
*
FROM
(
SELECT
EMPID,NAME, HIRE_DATE, SALARY,
MAX(HIRE_DATE) OVER (ORDER BY HIRE_DATE
RANGE BETWEEN UNBOUNDED PRECEDING
AND INTERVAL '1 DAY' PRECEDING
)
AS PREV_HIRE_DATE
FROM
EMPLOYEE
)
EMPS
LEFT JOIN
(
SELECT
HIRE_DATE,
COUNT(*) AS COUNT_EMPS,
MIN(SALARY) AS MIN_SALARY
FROM
EMPLOYEE
GROUP BY
HIRE_DATE
)
PREV_EMPS
ON PREV_EMPS.HIRE_DATE = EMPS.PREV_HIRE_DATE


EDIT:



Maybe try something like this? (I have to run, good luck!)



WITH
ranked AS
(
SELECT
*,
DENSE_RANK() OVER (ORDER BY HIRE_DATE) AS HIRE_SEQ_ID
FROM
EMPLOYEE
)
SELECT
*,
MIN(SALARY) OVER (ORDER BY HIRE_SEQ_ID
RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING
)
AS PREV_MIN_SALARY,
COUNT(*) OVER (ORDER BY HIRE_SEQ_ID
RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING
)
AS COUNT_PREV_EMPS
FROM
ranked






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 21 '18 at 15:59

























answered Nov 21 '18 at 15:51









MatBailie

58.9k1374110




58.9k1374110












  • @zulfi123786 Any luck?
    – MatBailie
    Nov 22 '18 at 9:22


















  • @zulfi123786 Any luck?
    – MatBailie
    Nov 22 '18 at 9:22
















@zulfi123786 Any luck?
– MatBailie
Nov 22 '18 at 9:22




@zulfi123786 Any luck?
– MatBailie
Nov 22 '18 at 9:22













0














This does what you're after, I believe (I've left it as an exercise for you to find the difference between the max and min salaries!):



WITH employee AS (SELECT 100 empid, 'Ravi' NAME, to_date('01/01/2018', 'dd/mm/yyyy') hire_date, 5000 salary FROM dual UNION ALL
SELECT 101 empid, 'Kumar' NAME, to_date('01/01/2018', 'dd/mm/yyyy') hire_date, 7000 salary FROM dual UNION ALL
SELECT 102 empid, 'Satish' NAME, to_date('01/01/2018', 'dd/mm/yyyy') hire_date, 13000 salary FROM dual UNION ALL
SELECT 103 empid, 'Naresh' NAME, to_date('02/01/2018', 'dd/mm/yyyy') hire_date, 7500 salary FROM dual UNION ALL
SELECT 104 empid, 'Lalith' NAME, to_date('04/01/2018', 'dd/mm/yyyy') hire_date, 17300 salary FROM dual UNION ALL
SELECT 105 empid, 'Suresh' NAME, to_date('04/01/2018', 'dd/mm/yyyy') hire_date, 40000 salary FROM dual UNION ALL
SELECT 106 empid, 'Latha' NAME, to_date('01/02/2018', 'dd/mm/yyyy') hire_date, 16000 salary FROM dual)
SELECT empid,
NAME,
hire_date,
salary,
COUNT(*) OVER (ORDER BY hire_date RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING) prev_day_hire_count,
MIN(salary) OVER (ORDER BY hire_date RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING) prev_day_min_sal,
MAX(salary) OVER (ORDER BY hire_date RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING) prev_day_max_sal
FROM employee;

EMPID NAME HIRE_DATE SALARY PREV_DAY_HIRE_COUNT PREV_DAY_MIN_SAL PREV_DAY_MAX_SAL
---------- ------ ----------- ---------- ------------------- ---------------- ----------------
100 Ravi 01/01/2018 5000 0
101 Kumar 01/01/2018 7000 0
102 Satish 01/01/2018 13000 0
103 Naresh 02/01/2018 7500 3 5000 13000
104 Lalith 04/01/2018 17300 0
105 Suresh 04/01/2018 40000 0
106 Latha 01/02/2018 16000 0





share|improve this answer





















  • The row with EMPID 104 should get PREV_DAY_MIN_SAL=7500. For this record the prior date is '02/01/2018' and there is only one record so consider 7500.
    – zulfi123786
    Nov 21 '18 at 16:36
















0














This does what you're after, I believe (I've left it as an exercise for you to find the difference between the max and min salaries!):



WITH employee AS (SELECT 100 empid, 'Ravi' NAME, to_date('01/01/2018', 'dd/mm/yyyy') hire_date, 5000 salary FROM dual UNION ALL
SELECT 101 empid, 'Kumar' NAME, to_date('01/01/2018', 'dd/mm/yyyy') hire_date, 7000 salary FROM dual UNION ALL
SELECT 102 empid, 'Satish' NAME, to_date('01/01/2018', 'dd/mm/yyyy') hire_date, 13000 salary FROM dual UNION ALL
SELECT 103 empid, 'Naresh' NAME, to_date('02/01/2018', 'dd/mm/yyyy') hire_date, 7500 salary FROM dual UNION ALL
SELECT 104 empid, 'Lalith' NAME, to_date('04/01/2018', 'dd/mm/yyyy') hire_date, 17300 salary FROM dual UNION ALL
SELECT 105 empid, 'Suresh' NAME, to_date('04/01/2018', 'dd/mm/yyyy') hire_date, 40000 salary FROM dual UNION ALL
SELECT 106 empid, 'Latha' NAME, to_date('01/02/2018', 'dd/mm/yyyy') hire_date, 16000 salary FROM dual)
SELECT empid,
NAME,
hire_date,
salary,
COUNT(*) OVER (ORDER BY hire_date RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING) prev_day_hire_count,
MIN(salary) OVER (ORDER BY hire_date RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING) prev_day_min_sal,
MAX(salary) OVER (ORDER BY hire_date RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING) prev_day_max_sal
FROM employee;

EMPID NAME HIRE_DATE SALARY PREV_DAY_HIRE_COUNT PREV_DAY_MIN_SAL PREV_DAY_MAX_SAL
---------- ------ ----------- ---------- ------------------- ---------------- ----------------
100 Ravi 01/01/2018 5000 0
101 Kumar 01/01/2018 7000 0
102 Satish 01/01/2018 13000 0
103 Naresh 02/01/2018 7500 3 5000 13000
104 Lalith 04/01/2018 17300 0
105 Suresh 04/01/2018 40000 0
106 Latha 01/02/2018 16000 0





share|improve this answer





















  • The row with EMPID 104 should get PREV_DAY_MIN_SAL=7500. For this record the prior date is '02/01/2018' and there is only one record so consider 7500.
    – zulfi123786
    Nov 21 '18 at 16:36














0












0








0






This does what you're after, I believe (I've left it as an exercise for you to find the difference between the max and min salaries!):



WITH employee AS (SELECT 100 empid, 'Ravi' NAME, to_date('01/01/2018', 'dd/mm/yyyy') hire_date, 5000 salary FROM dual UNION ALL
SELECT 101 empid, 'Kumar' NAME, to_date('01/01/2018', 'dd/mm/yyyy') hire_date, 7000 salary FROM dual UNION ALL
SELECT 102 empid, 'Satish' NAME, to_date('01/01/2018', 'dd/mm/yyyy') hire_date, 13000 salary FROM dual UNION ALL
SELECT 103 empid, 'Naresh' NAME, to_date('02/01/2018', 'dd/mm/yyyy') hire_date, 7500 salary FROM dual UNION ALL
SELECT 104 empid, 'Lalith' NAME, to_date('04/01/2018', 'dd/mm/yyyy') hire_date, 17300 salary FROM dual UNION ALL
SELECT 105 empid, 'Suresh' NAME, to_date('04/01/2018', 'dd/mm/yyyy') hire_date, 40000 salary FROM dual UNION ALL
SELECT 106 empid, 'Latha' NAME, to_date('01/02/2018', 'dd/mm/yyyy') hire_date, 16000 salary FROM dual)
SELECT empid,
NAME,
hire_date,
salary,
COUNT(*) OVER (ORDER BY hire_date RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING) prev_day_hire_count,
MIN(salary) OVER (ORDER BY hire_date RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING) prev_day_min_sal,
MAX(salary) OVER (ORDER BY hire_date RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING) prev_day_max_sal
FROM employee;

EMPID NAME HIRE_DATE SALARY PREV_DAY_HIRE_COUNT PREV_DAY_MIN_SAL PREV_DAY_MAX_SAL
---------- ------ ----------- ---------- ------------------- ---------------- ----------------
100 Ravi 01/01/2018 5000 0
101 Kumar 01/01/2018 7000 0
102 Satish 01/01/2018 13000 0
103 Naresh 02/01/2018 7500 3 5000 13000
104 Lalith 04/01/2018 17300 0
105 Suresh 04/01/2018 40000 0
106 Latha 01/02/2018 16000 0





share|improve this answer












This does what you're after, I believe (I've left it as an exercise for you to find the difference between the max and min salaries!):



WITH employee AS (SELECT 100 empid, 'Ravi' NAME, to_date('01/01/2018', 'dd/mm/yyyy') hire_date, 5000 salary FROM dual UNION ALL
SELECT 101 empid, 'Kumar' NAME, to_date('01/01/2018', 'dd/mm/yyyy') hire_date, 7000 salary FROM dual UNION ALL
SELECT 102 empid, 'Satish' NAME, to_date('01/01/2018', 'dd/mm/yyyy') hire_date, 13000 salary FROM dual UNION ALL
SELECT 103 empid, 'Naresh' NAME, to_date('02/01/2018', 'dd/mm/yyyy') hire_date, 7500 salary FROM dual UNION ALL
SELECT 104 empid, 'Lalith' NAME, to_date('04/01/2018', 'dd/mm/yyyy') hire_date, 17300 salary FROM dual UNION ALL
SELECT 105 empid, 'Suresh' NAME, to_date('04/01/2018', 'dd/mm/yyyy') hire_date, 40000 salary FROM dual UNION ALL
SELECT 106 empid, 'Latha' NAME, to_date('01/02/2018', 'dd/mm/yyyy') hire_date, 16000 salary FROM dual)
SELECT empid,
NAME,
hire_date,
salary,
COUNT(*) OVER (ORDER BY hire_date RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING) prev_day_hire_count,
MIN(salary) OVER (ORDER BY hire_date RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING) prev_day_min_sal,
MAX(salary) OVER (ORDER BY hire_date RANGE BETWEEN 1 PRECEDING AND 1 PRECEDING) prev_day_max_sal
FROM employee;

EMPID NAME HIRE_DATE SALARY PREV_DAY_HIRE_COUNT PREV_DAY_MIN_SAL PREV_DAY_MAX_SAL
---------- ------ ----------- ---------- ------------------- ---------------- ----------------
100 Ravi 01/01/2018 5000 0
101 Kumar 01/01/2018 7000 0
102 Satish 01/01/2018 13000 0
103 Naresh 02/01/2018 7500 3 5000 13000
104 Lalith 04/01/2018 17300 0
105 Suresh 04/01/2018 40000 0
106 Latha 01/02/2018 16000 0






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 21 '18 at 16:18









Boneist

17.9k11028




17.9k11028












  • The row with EMPID 104 should get PREV_DAY_MIN_SAL=7500. For this record the prior date is '02/01/2018' and there is only one record so consider 7500.
    – zulfi123786
    Nov 21 '18 at 16:36


















  • The row with EMPID 104 should get PREV_DAY_MIN_SAL=7500. For this record the prior date is '02/01/2018' and there is only one record so consider 7500.
    – zulfi123786
    Nov 21 '18 at 16:36
















The row with EMPID 104 should get PREV_DAY_MIN_SAL=7500. For this record the prior date is '02/01/2018' and there is only one record so consider 7500.
– zulfi123786
Nov 21 '18 at 16:36




The row with EMPID 104 should get PREV_DAY_MIN_SAL=7500. For this record the prior date is '02/01/2018' and there is only one record so consider 7500.
– zulfi123786
Nov 21 '18 at 16:36


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53415289%2fneed-help-understanding-range-between-in-sql-window-functions%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

404 Error Contact Form 7 ajax form submitting

How to know if a Active Directory user can login interactively

TypeError: fit_transform() missing 1 required positional argument: 'X'