I have situation where I am generating a list of Dates from a function that is working fine.
My goal is to generate N number of rows (1-10) for each DATE/EMPLOYEE_ID combination. Below is some sample output for a single day. As you can see for 07282021 there is a random number of rows for each employee_id.
EMPLOYEE_ID CARD_NUM LOCATION_ID ACCESS_DATE
1 F123456 10 07282021 09:47:48
1 F123456 5 07282021 19:17:42
2 R33432 1 4 07282021 02:00:37
3 C765341 2 07282021 17:33:57
3 C765341 6 07282021 17:33:57
3 C765341 1 07282021 18:53:07
4 D564311 6 07282021 03:06:37
After an arduous task of Googling, reading and asking around I have a solution that is almost there.
The last problem that I can't seem to figure out how to solve based on my code below is there are some missing dates in the output. In addition, along with some missing employee_id for each date.
Yes, I am aware that all the the times in my example are set to midnight and I'll fix that as soon as the code is working.
I was hoping someone can take a look at my test CASE and tell me what the issues are and provide a solution. Thanks in advance for your expertise and to all who answer.
BTW, I will try to format my code before posting.
ALTER SESSION SET
NLS_DATE_FORMAT = 'MMDDYYYY HH24:MI:SS';
CREATE OR REPLACE TYPE nt\_date IS TABLE OF DATE;
CREATE OR REPLACE FUNCTION generate\_dates\_pipelined(
p\_from IN DATE,
p\_to IN DATE
)
RETURN nt\_date PIPELINED DETERMINISTIC
IS
v\_start DATE := TRUNC(LEAST(p\_from, p\_to));
v\_end DATE := TRUNC(GREATEST(p\_from, p\_to));
BEGIN
LOOP
PIPE ROW (v\_start);
EXIT WHEN v\_start >= v\_end;
v\_start := v\_start + INTERVAL '1' DAY;
END LOOP;
RETURN;
END generate\_dates\_pipelined;
Create table employees(
employee\_id NUMBER(6),
first\_name VARCHAR2(20),
last\_name VARCHAR2(20),
card\_num VARCHAR2(10),
work\_days VARCHAR2(7)
);
ALTER TABLE employees
ADD (
CONSTRAINT employees\_pk PRIMARY KEY (employee\_id)
);
INSERT INTO employees (
EMPLOYEE\_ID,
first\_name,
last\_name,
card\_num,
work\_days
)
WITH names AS (
SELECT 1, 'Jane', 'Doe', 'F123456', 'NYYYYYN' FROM dual UNION ALL
SELECT 2, 'Madison', 'Smith', 'R33432','NYYYYYN' FROM dual UNION ALL
SELECT 3, 'Justin', 'Case', 'C765341','NYYYYYN' FROM dual UNION ALL
SELECT 4, 'Mike', 'Jones', 'D564311','NYYYYYN' FROM dual )
SELECT \* FROM names;
CREATE TABLE locations AS
SELECT level AS location\_id,
'Door ' || level AS location\_name,
CASE round(dbms\_random.value(1,3))
WHEN 1 THEN 'A'
WHEN 2 THEN 'T'
WHEN 3 THEN 'G'
END AS location\_type
FROM dual
CONNECT BY level \<= 10;
ALTER TABLE locations
ADD ( CONSTRAINT locations\_pk
PRIMARY KEY (location\_id));
SELECT e.employee_id,
e.card_num,
l.location_id,
c.access_date
FROM (
SELECT employee_id,
round ( dbms_random.value ( 1, 10 ) ) rn,
card_num
FROM employees
) e
INNER JOIN
( SELECT COLUMN_VALUE AS access_date,
row_number() OVER (ORDER BY dbms_random.value) AS rn
FROM TABLE(generate_dates_pipelined(SYSDATE, ADD_MONTHS(SYSDATE, 1)))
) c
ON (e.rn >= c.rn)
CROSS APPLY (
SELECT * FROM (
SELECT location_id,
row_number() OVER (ORDER BY dbms_random.value) AS rn
FROM locations
) l
WHERE l.rn <= c.rn
FETCH FIRST 1 ROWS ONLY
) l
ORDER BY
access_date,
employee_id,
location_id;