SELECT ID,INDEX,purchase_list,
NVL(CASE WHEN INDEX = 2 THEN purchase_list END,0)
AS qty,
sum(NVL(CASE WHEN INDEX = 2 THEN purchase_list END,0))over(partition by ID) as order_qty
FROM (
SELECT ID,index,d.value::string AS purchase_list FROM (
SELECT ID,c.value::string AS purchase_list
FROM table_1,LATERAL flatten(INPUT=>split(post_purchase_list, '|')) c
), LATERAL flatten(INPUT=>split(purchase_list, ';')) d
)WHERE ID=1250707
When I run the above query, I'm getting
Numeric value is not recognized.
The column - post_purchase_list is a VARCHAR column.
SELECT 'this is a string' as this_is_a_str,
NVL(this_is_a_str, 0) as one_of_these_is_str_and_the_other_is_a_number;
also gives:
Numeric value 'this is a string' is not recognized
Which to say, your types are different, ether cast your "string to a number if it is one" or cast your zero to a string '0'
SELECT '1234' as this_is_a_str,
0 as this_is_a_number,
NVL(this_is_a_str, this_is_a_number::string),
NVL(this_is_a_str::int, this_is_a_number);
this works just fine. Now for you code you are doing this twice.
SELECT
ID,
INDEX,
purchase_list,
NVL(CASE WHEN INDEX = 2 THEN purchase_list END, '0') AS qty,
sum(NVL(CASE WHEN INDEX = 2 THEN purchase_list END, '0')) over (partition by ID) as order_qty
FROM (
SELECT
ID,
index,
d.value::string AS purchase_list
FROM (
SELECT
ID,
c.value::string AS purchase_list
FROM table_1,
LATERAL flatten(INPUT=>split(post_purchase_list, '|')) c
), LATERAL flatten(INPUT=>split(purchase_list, ';')) d
)
WHERE ID = 1250707
but as mentioned before those flattens could be written
SELECT
ID,
INDEX,
purchase_list,
NVL(CASE WHEN INDEX = 2 THEN purchase_list END,'0') AS qty,
sum(NVL(CASE WHEN INDEX = 2 THEN purchase_list END,'0')) over (partition by ID) as order_qty
FROM (
SELECT
ID,
d.index,
d.value::string AS purchase_list
FROM table_1
,LATERAL flatten(INPUT=>split(post_purchase_list, '|')) c
,LATERAL flatten(INPUT=>split(c.value::string, ';')) d
)
WHERE ID = 1250707
and the qty can be reused:
SELECT
ID,
INDEX,
purchase_list,
NVL(CASE WHEN INDEX = 2 THEN purchase_list END,'0') AS qty,
sum(qty) over (partition by ID) as order_qty
FROM (
SELECT
ID,
d.index,
d.value::string AS purchase_list
FROM table_1
,LATERAL flatten(INPUT=>split(post_purchase_list, '|')) c
,LATERAL flatten(INPUT=>split(c.value::string, ';')) d
)
WHERE ID = 1250707
OR
SELECT
ID,
d.index,
d.value::string AS purchase_list,
NVL(CASE WHEN d.index = 2 THEN purchase_list END, '0') AS qty,
sum(qty) over (partition by ID) as order_qty
FROM table_1
,LATERAL flatten(INPUT=>split(post_purchase_list, '|')) c
,LATERAL flatten(INPUT=>split(c.value::string, ';')) d
WHERE ID = 1250707
Related
WITH CTE AS (
SELECT
id,
c_no,
TRY_CAST(B.p_no as INTEGER) as p_no
FROM db_name.schema_name.tbl_1 A
JOIN db_name.schema_name.tbl_2 B
ON B.id_col = A.id_col
WHERE flg_col = '0'
AND cd NOT IN ('1','2','3','4')
AND DATE = '2022-02-02'
AND id='12345678'
ORDER BY p_no
)
SELECT
id,
LISTAGG (distinct c_no , ',') WITHIN GROUP (ORDER BY c_no) AS c01
FROM CTE
GROUP BY id;
When I run the above query, I'm getting result AS
Row ID C01
1 01 110,118,id_not_found,no_record
2 02 id_found
3 03 no_record
I want to display only the numberic values in C01 column in the result along with the corresponding ID. I want to ignore
these 2 values - id_not_found & no_record in the first row.
But in 2nd and 3rd, the value should remain same.
Any suggestions please.
Try to use the TRY_TO_NUMBER function:
WITH CTE AS (
SELECT
id,
c_no,
TRY_CAST(B.p_no as INTEGER) as p_no
FROM db_name.schema_name.tbl_1 A
JOIN db_name.schema_name.tbl_2 B
ON B.id_col = A.id_col
WHERE flg_col = '0'
AND cd NOT IN ('1','2','3','4')
AND DATE = '2022-02-02'
AND id='12345678'
ORDER BY p_no
)
SELECT
id,
IFNULL(LISTAGG(distinct TRY_TO_NUMBER(c_no) , ',') WITHIN GROUP(ORDER BY TRY_TO_NUMBER(c_no)), c_no) AS c01
FROM CTE
GROUP BY id;
The way you have describe it, is if "there are any number of include numbers, other all data is valid"
Using the smallest SQL that demonstrates the code and we do a little preconditioning in a CTE (which could be moved into your CTE)
WITH cte(id, c_no) AS (
SELECT * FROM VALUES
(01, '110'),
(01, '118'),
(01, 'id_not_found'),
(01, 'no_record'),
(02, 'id_found'),
(03, 'no_record')
), pre_condition AS (
SELECT *,
try_to_number(c_no) as c_no_as_num
FROM cte
)
SELECT
id,
count(c_no_as_num) as count_of_nums,
LISTAGG (distinct c_no , ',') WITHIN GROUP (ORDER BY c_no) AS c01_all,
LISTAGG (distinct c_no_as_num , ',') WITHIN GROUP (ORDER BY c_no_as_num) AS c01_nums,
IFF(count_of_nums>0, c01_nums, c01_all) AS c01
FROM pre_condition
GROUP BY id
ORDER BY id;
we get, the answer you want in C01:
ID
COUNT_OF_NUMS
C01_ALL
C01_NUMS
C01
1
2
110,118,id_not_found,no_record
110,118
110,118
2
0
id_found
id_found
3
0
no_record
no_record
so we can mash this smaller:
SELECT * FROM VALUES
(01, '110'),
(01, '118'),
(01, 'id_not_found'),
(01, 'no_record'),
(02, 'id_found'),
(03, 'no_record')
), pre_condition AS (
SELECT *,
try_to_number(c_no) as c_no_as_num
FROM cte
)
SELECT
id,
IFF(count(c_no_as_num)>0, LISTAGG (distinct c_no_as_num , ',') WITHIN GROUP (ORDER BY c_no_as_num), LISTAGG (distinct c_no , ',') WITHIN GROUP (ORDER BY c_no)) AS c01
FROM pre_condition
GROUP BY id
ORDER BY id;
and weave that into your code as:
WITH CTE AS (
SELECT
id,
c_no,
try_to_number(c_no) as c_no_as_num
TRY_CAST(B.p_no as INTEGER) as p_no
FROM db_name.schema_name.tbl_1 A
JOIN db_name.schema_name.tbl_2 B
ON B.id_col = A.id_col
WHERE flg_col = '0'
AND DATE = '2022-02-02'
AND id = '12345678'
AND cd NOT IN ('1','2','3','4')
)
SELECT
id,
IFF(count(c_no_as_num)>0
,LISTAGG (distinct c_no_as_num , ',') WITHIN GROUP (ORDER BY c_no_as_num)
,LISTAGG (distinct c_no , ',') WITHIN GROUP (ORDER BY c_no)
) AS c01
FROM cte
GROUP BY id
;
I have this example where Id1 serves as the group and Id2 is an Id unique in the group.
If Id2 is the same as Id1, I want to get its row as a representative of the whole group.
If there's no Id1 that matched to Id2, then I want to get the first row based on the order of ascending Id2.
This is how I did it but I just wonder how I can simplify the tsql:
WITH cte AS
(
SELECT 'A' AS Id1, '1' AS Id2, 'DSFSF' AS _detail
UNION ALL
SELECT 'A' AS Id1, '2' AS Id2, 'ASDF' AS _detail
UNION ALL
SELECT 'A' AS Id1, 'A' AS Id2, '434242' AS _detail
UNION ALL
SELECT 'B' AS Id1, '1' AS Id2, 'gsreew' AS _detail
UNION ALL
SELECT 'B' AS Id1, '2' AS Id2, 'werw' AS _detail
UNION ALL
SELECT 'B' AS Id1, '3' AS Id2, '67575' AS _detail
),
cte2 AS
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY Id1 ORDER BY Id2) AS rn,
CASE
WHEN Id1 = Id2 THEN 1 ELSE 0
END AS _matchedid
FROM
cte
),
cte3 AS
(
SELECT
Id1, SUM(_matchedid) AS _matched
FROM
cte2
GROUP BY
Id1
)
SELECT *
FROM cte2 a
INNER JOIN cte3 b ON a.Id1 = b.Id1
WHERE b._matched = 1 AND a.Id1 = a.Id2
UNION ALL
SELECT *
FROM cte2 a
INNER JOIN cte3 b ON a.Id1 = b.Id1
WHERE b._matched = 0 AND a.rn = 1
You can use a conditional row-numbering solution for this
WITH cte AS
(
SELECT 'A' AS Id1, '1' AS Id2, 'DSFSF' AS _detail
UNION ALL
SELECT 'A' AS Id1, '2' AS Id2, 'ASDF' AS _detail
UNION ALL
SELECT 'A' AS Id1, 'A' AS Id2, '434242' AS _detail
UNION ALL
SELECT 'B' AS Id1, '1' AS Id2, 'gsreew' AS _detail
UNION ALL
SELECT 'B' AS Id1, '2' AS Id2, 'werw' AS _detail
UNION ALL
SELECT 'B' AS Id1, '3' AS Id2, '67575' AS _detail
),
cteWithRn AS
(
SELECT *
ROW_NUMBER() OVER (PARTITION BY Id1, CASE WHEN Id1 = Id2 THEN 0 ELSE 1 END, Id2) AS rn
FROM cte
)
SELECT *
FROM cteWithRn
WHERE rn = 1;
One idea uses TOP (1) WITH TIES and ROW_NUMBER with a conditional ORDER BY:
SELECT TOP (1) WITH TIES *
FROM CTE
ORDER BY ROW_NUMBER() OVER (PARTITION BY ID1 ORDER BY CASE ID1 WHEN ID2 THEN NULL ELSE ID2 END);
Note that as your column ID2 is a varchar, then a value like '10' will have a lower value than something like '2'.
Query 1:
select * from(select* from (select Product_ID, batchno, Baleno,
SampleTime, Line, ItemData, ItemType from ItemData) d
pivot(sum(ItemData) for ItemType in (DYL, COLOR, STD)) as piv1) ff
where batchno = '001' AND Product_ID = '1' And Line = 'B'
Query 2:
select * from(select* from (select Product_ID, batchno, Baleno, SampleTime,
Line, ItemData, ItemType from ItemData) d
pivot(sum(ItemData) for ItemType in (DYL, COLOR, STD)) as piv1) ff
where batchno = '001' AND Product_ID = '1' And Line = 'A'
Use UNION ALL As below-
SELECT *
FROM
(
SELECT *
FROM
(
SELECT Product_ID,
batchno,
Baleno,
SampleTime,
Line,
ItemData,
ItemType
FROM ItemData
) d PIVOT(SUM(ItemData) FOR ItemType IN(DYL, COLOR, STD)) AS piv1
) ff
WHERE batchno = '001' AND Product_ID = '1' AND Line = 'B';
UNION ALL
SELECT *
FROM
(
SELECT *
FROM
(
SELECT Product_ID,
batchno,
Baleno,
SampleTime,
Line,
ItemData,
ItemType
FROM ItemData
) d PIVOT(SUM(ItemData) FOR ItemType IN(DYL, COLOR, STD)) AS piv1
) ff
WHERE batchno = '001' AND Product_ID = '1' AND Line = 'A';
Below are three different cursors: POTENTIAL_USERS, NO_WORKFLOWS, and NO_MAPPINGS. I am trying to find a way to delete from the POTENTIAL USERS CURSOR where it is found in the NO_MAPPINGS and also the NO_WORKFLOWS cursors. I am using cursors because the queries they are referencing are rather long, and this makes it easier for me to follow. Also, the NO_WORKFLOWS and NO_MAPPINGS is referencing two different WITH statements, which I substituted instead of using views because I am in a read-only database, and the POTENTIAL_USERS references a query that pulls out inactive user accounts. I gathered the error messages from creating a similar scenario in another database. I would appreciate any advice or recommendations.
CURSOR USERS_WITHOUT_CHECKEDOUT_WORKFLOWS
IS
WITH POTENTIAL_USERS_TO_DELETE
AS (SELECT USER_NAME, USER_ID
FROM GAI_PM.REP_USERS
WHERE USER_NAME NOT IN
(SELECT USER_NAME
FROM (SELECT ROW_NUMBER ()
OVER (
PARTITION BY REP_USERS.USER_NAME
ORDER BY
TO_DATE (
SUBSTR (
LAST_SAVED,
1,
10),
'MM/DD/YYYY') DESC)
RN,
REP_USERS.USER_NAME,
REP_VERSION_PROPS.LAST_SAVED
FROM GAI_PM.REP_USERS
JOIN
GAI_PM.REP_VERSION_PROPS
ON REP_USERS.USER_ID =
REP_VERSION_PROPS.USER_ID)
WHERE RN = 1
AND TO_DATE (SUBSTR (LAST_SAVED, 1, 10),
'MM/DD/YYYY') >
ADD_MONTHS (TRUNC (SYSDATE), -12))
AND UPPER (REP_USERS.USER_NAME) NOT LIKE '%ADMIN%'
AND UPPER (REP_USERS.USER_NAME) NOT LIKE
'%CSTEINKAMP%'),
CHECKED_OUT_WORKFLOWS
AS (SELECT C.SUBJ_NAME,
A.TASK_NAME,
B.USER_NAME,
USER_ID
FROM GAI_PM.OPB_TASK A
JOIN GAI_PM.OPB_USERS B
ON A.CHECKOUT_USER_ID = B.USER_ID
JOIN GAI_PM.OPB_SUBJECT C
ON A.SUBJECT_ID = C.SUBJ_ID
WHERE A.CHECKOUT_USER_ID <> 0)
SELECT DISTINCT POTENTIAL_USERS_TO_DELETE.USER_NAME
FROM POTENTIAL_USERS_TO_DELETE
LEFT JOIN
CHECKED_OUT_WORKFLOWS
ON POTENTIAL_USERS_TO_DELETE.USER_ID =
CHECKED_OUT_WORKFLOWS.USER_ID
WHERE CHECKED_OUT_WORKFLOWS.USER_NAME IS NULL;
CURSOR POTENTIAL_USERS_TO_DELETE
IS
SELECT USER_NAME AS "USERS TO DELETE"
FROM GAI_PM.REP_USERS
WHERE USER_NAME NOT IN
(SELECT USER_NAME
FROM (SELECT ROW_NUMBER ()
OVER (
PARTITION BY REP_USERS.USER_NAME
ORDER BY
TO_DATE (
SUBSTR (
LAST_SAVED,
1,
10),
'MM/DD/YYYY') DESC)
RN,
REP_USERS.USER_NAME,
REP_VERSION_PROPS.LAST_SAVED
FROM GAI_PM.REP_USERS
JOIN
GAI_PM.REP_VERSION_PROPS
ON REP_USERS.USER_ID =
REP_VERSION_PROPS.USER_ID)
WHERE RN = 1
AND TO_DATE (SUBSTR (LAST_SAVED, 1, 10),
'MM/DD/YYYY') >
ADD_MONTHS (TRUNC (SYSDATE), -12))
AND UPPER (REP_USERS.USER_NAME) NOT LIKE '%ADMIN%'
AND UPPER (REP_USERS.USER_NAME) NOT LIKE '%CSTEINKAMP%';
BEGIN
DECLARE
CURSOR USERS_WITHOUT_CHECKEDOUT_MAPPINGS
IS
WITH POTENTIAL_USERS_TO_DELETE
AS (SELECT USER_NAME, USER_ID
FROM GAI_PM.REP_USERS
WHERE USER_NAME NOT IN
(SELECT USER_NAME
FROM (SELECT ROW_NUMBER ()
OVER (
PARTITION BY REP_USERS.USER_NAME
ORDER BY
TO_DATE (
SUBSTR (
LAST_SAVED,
1,
10),
'MM/DD/YYYY') DESC)
RN,
REP_USERS.USER_NAME,
REP_VERSION_PROPS.LAST_SAVED
FROM GAI_PM.REP_USERS
JOIN
GAI_PM.REP_VERSION_PROPS
ON REP_USERS.USER_ID =
REP_VERSION_PROPS.USER_ID)
WHERE RN = 1
AND TO_DATE (SUBSTR (LAST_SAVED, 1, 10),
'MM/DD/YYYY') >
ADD_MONTHS (TRUNC (SYSDATE), -12))
AND UPPER (REP_USERS.USER_NAME) NOT LIKE '%ADMIN%'
AND UPPER (REP_USERS.USER_NAME) NOT LIKE
'%CSTEINKAMP%'),
CHECKED_OUT_MAPPINGS
AS (SELECT C.SUBJ_NAME,
A.MAPPING_NAME,
B.USER_NAME,
B.USER_ID
FROM GAI_PM.OPB_MAPPING A
JOIN GAI_PM.OPB_USERS B
ON A.CHECKOUT_USER_ID = B.USER_ID
JOIN GAI_PM.OPB_SUBJECT C
ON A.SUBJECT_ID = C.SUBJ_ID
WHERE A.CHECKOUT_USER_ID <> 0)
SELECT DISTINCT POTENTIAL_USERS_TO_DELETE.USER_NAME, MAPPING_NAME
FROM POTENTIAL_USERS_TO_DELETE
LEFT JOIN
CHECKED_OUT_MAPPINGS
ON POTENTIAL_USERS_TO_DELETE.USER_ID =
CHECKED_OUT_MAPPINGS.USER_ID
WHERE CHECKED_OUT_MAPPINGS.USER_NAME IS NULL;
POTENTIAL_USERS POTENTIAL_USERS_TO_DELETE%ROWTYPE;
NO_WORKFLOWS USERS_WITHOUT_CHECKEDOUT_WORKFLOWS%ROWTYPE;
NO_MAPPINGS USERS_WITHOUT_CHECKEDOUT_MAPPINGS%ROWTYPE;
BEGIN
LOOP
IF NOT (POTENTIAL_USERS_TO_DELETE%ISOPEN)
THEN
OPEN POTENTIAL_USERS_TO_DELETE;
END IF;
IF NOT (USERS_WITHOUT_CHECKEDOUT_WORKFLOWS%ISOPEN)
THEN
OPEN USERS_WITHOUT_CHECKEDOUT_WORKFLOWS;
END IF;
IF NOT (USERS_WITHOUT_CHECKEDOUT_MAPPINGS%ISOPEN)
THEN
OPEN USERS_WITHOUT_CHECKEDOUT_MAPPINGS;
END IF;
FETCH POTENTIAL_USERS_TO_DELETE INTO POTENTIAL_USERS;
FETCH USERS_WITHOUT_CHECKEDOUT_WORKFLOWS INTO NO_WORKFLOWS;
FETCH USERS_WITHOUT_CHECKEDOUT_MAPPINGS INTO NO_MAPPINGS;
DELETE FROM POTENTIAL_USERS
WHERE POTENTIAL_USERS.USER_NAME = NO_WORKFLOWS.USER_NAME
OR POTENTIAL_USERS.USER_NAME = NO_MAPPINGS.USER_NAME;
IF (POTENTIAL_USERS_TO_DELETE%ISOPEN)
THEN
CLOSE POTENTIAL_USERS_TO_DELETE;
END IF;
IF (USERS_WITHOUT_CHECKEDOUT_WORKFLOWS%ISOPEN)
THEN
CLOSE USERS_WITHOUT_CHECKEDOUT_WORKFLOWS;
END IF;
IF (USERS_WITHOUT_CHECKEDOUT_MAPPINGS%ISOPEN)
THEN
CLOSE USERS_WITHOUT_CHECKEDOUT_MAPPINGS;
END IF;
END LOOP;
END;
END;
These are the error messages I keep getting:
ORA-06550: line 22, column 29:
PLS-00103: Encountered the symbol "NO_WORKFLOWS" when expecting one of the following:
(
The symbol "(" was substituted for "NO_WORKFLOWS" to continue.
ORA-06550: line 23, column 3:
PLS-00103: Encountered the symbol "THEN" when expecting one of the following:
) , and or as
The symbol ")" was substituted for "THEN" to continue.
ORA-06550: line 26, column 40:
PLS-00103: Encountered the symbol "NO_WORKFLOWS" when expecting one of the following:
(
The symbol "(" was substituted for "NO_WORKFLOWS" to continue.
ORA-06550: line 27, column 44:
PLS-00103: Encountered the symbol "NO_MAPPINGS" when expecting one of the following:
(
I realized I was making this way too difficult. All I had to do was split the queries into two separate delete scripts, and then just run each of them separately or as a script.
--Finds and deletes users with no access for past year
--and sees if they have any checked out workflows.
DELETE USER_NAME
FROM (SELECT USER_NAME
FROM GAI_PM.REP_USERS
WHERE USER_NAME NOT IN
(SELECT USER_NAME
FROM (SELECT ROW_NUMBER ()
OVER (
PARTITION BY REP_USERS.USER_NAME
ORDER BY
TO_DATE (
SUBSTR (
LAST_SAVED,
1,
10),
'MM/DD/YYYY') DESC)
RN,
REP_USERS.USER_NAME,
REP_VERSION_PROPS.LAST_SAVED
FROM GAI_PM.REP_USERS
JOIN
GAI_PM.REP_VERSION_PROPS
ON REP_USERS.USER_ID =
REP_VERSION_PROPS.USER_ID)
WHERE RN = 1
AND TO_DATE (SUBSTR (LAST_SAVED, 1, 10),
'MM/DD/YYYY') >
ADD_MONTHS (TRUNC (SYSDATE), -12))
AND UPPER (REP_USERS.USER_NAME) NOT LIKE '%ADMIN%'
AND UPPER (REP_USERS.USER_NAME) NOT LIKE '%CSTEINKAMP%')
WHERE USER_NAME IN
(WITH POTENTIAL_USERS_TO_DELETE
AS (SELECT USER_NAME, USER_ID
FROM GAI_PM.REP_USERS
WHERE USER_NAME NOT IN
(SELECT USER_NAME
FROM (SELECT ROW_NUMBER ()
OVER (
PARTITION BY REP_USERS.USER_NAME
ORDER BY
TO_DATE (
SUBSTR (
LAST_SAVED,
1,
10),
'MM/DD/YYYY') DESC)
RN,
REP_USERS.USER_NAME,
REP_VERSION_PROPS.LAST_SAVED
FROM GAI_PM.REP_USERS
JOIN
GAI_PM.REP_VERSION_PROPS
ON REP_USERS.USER_ID =
REP_VERSION_PROPS.USER_ID)
WHERE RN = 1
AND TO_DATE (
SUBSTR (LAST_SAVED, 1, 10),
'MM/DD/YYYY') >
ADD_MONTHS (TRUNC (SYSDATE),
-12))
AND UPPER (REP_USERS.USER_NAME) NOT LIKE '%ADMIN%'
AND UPPER (REP_USERS.USER_NAME) NOT LIKE
'%CSTEINKAMP%'),
CHECKED_OUT_WORKFLOWS
AS (SELECT C.SUBJ_NAME,
A.TASK_NAME,
B.USER_NAME,
USER_ID
FROM GAI_PM.OPB_TASK A
JOIN GAI_PM.OPB_USERS B
ON A.CHECKOUT_USER_ID = B.USER_ID
JOIN GAI_PM.OPB_SUBJECT C
ON A.SUBJECT_ID = C.SUBJ_ID
WHERE A.CHECKOUT_USER_ID <> 0)
SELECT DISTINCT POTENTIAL_USERS_TO_DELETE.USER_NAME
FROM POTENTIAL_USERS_TO_DELETE
LEFT JOIN
CHECKED_OUT_WORKFLOWS
ON POTENTIAL_USERS_TO_DELETE.USER_ID =
CHECKED_OUT_WORKFLOWS.USER_ID
WHERE CHECKED_OUT_WORKFLOWS.USER_NAME IS NULL);
--Finds and deletes users with no access for past year
--and sees if they have any checked out mappings.
DELETE USER_NAME
FROM (SELECT USER_NAME
FROM GAI_PM.REP_USERS
WHERE USER_NAME NOT IN
(SELECT USER_NAME
FROM (SELECT ROW_NUMBER ()
OVER (
PARTITION BY REP_USERS.USER_NAME
ORDER BY
TO_DATE (
SUBSTR (
LAST_SAVED,
1,
10),
'MM/DD/YYYY') DESC)
RN,
REP_USERS.USER_NAME,
REP_VERSION_PROPS.LAST_SAVED
FROM GAI_PM.REP_USERS
JOIN
GAI_PM.REP_VERSION_PROPS
ON REP_USERS.USER_ID =
REP_VERSION_PROPS.USER_ID)
WHERE RN = 1
AND TO_DATE (SUBSTR (LAST_SAVED, 1, 10),
'MM/DD/YYYY') >
ADD_MONTHS (TRUNC (SYSDATE), -12))
AND UPPER (REP_USERS.USER_NAME) NOT LIKE '%ADMIN%'
AND UPPER (REP_USERS.USER_NAME) NOT LIKE '%CSTEINKAMP%')
WHERE USER_NAME IN
(WITH POTENTIAL_USERS_TO_DELETE
AS (SELECT USER_NAME, USER_ID
FROM GAI_PM.REP_USERS
WHERE USER_NAME NOT IN
(SELECT USER_NAME
FROM (SELECT ROW_NUMBER ()
OVER (
PARTITION BY REP_USERS.USER_NAME
ORDER BY
TO_DATE (
SUBSTR (
LAST_SAVED,
1,
10),
'MM/DD/YYYY') DESC)
RN,
REP_USERS.USER_NAME,
REP_VERSION_PROPS.LAST_SAVED
FROM GAI_PM.REP_USERS
JOIN
GAI_PM.REP_VERSION_PROPS
ON REP_USERS.USER_ID =
REP_VERSION_PROPS.USER_ID)
WHERE RN = 1
AND TO_DATE (
SUBSTR (LAST_SAVED, 1, 10),
'MM/DD/YYYY') >
ADD_MONTHS (TRUNC (SYSDATE),
-12))
AND UPPER (REP_USERS.USER_NAME) NOT LIKE '%ADMIN%'
AND UPPER (REP_USERS.USER_NAME) NOT LIKE
'%CSTEINKAMP%'),
CHECKED_OUT_MAPPINGS
AS (SELECT C.SUBJ_NAME,
A.MAPPING_NAME,
B.USER_NAME,
B.USER_ID
FROM GAI_PM.OPB_MAPPING A
JOIN GAI_PM.OPB_USERS B
ON A.CHECKOUT_USER_ID = B.USER_ID
JOIN GAI_PM.OPB_SUBJECT C
ON A.SUBJECT_ID = C.SUBJ_ID
WHERE A.CHECKOUT_USER_ID <> 0)
SELECT DISTINCT POTENTIAL_USERS_TO_DELETE.USER_NAME
FROM POTENTIAL_USERS_TO_DELETE
LEFT JOIN
CHECKED_OUT_MAPPINGS
ON POTENTIAL_USERS_TO_DELETE.USER_ID =
CHECKED_OUT_MAPPINGS.USER_ID
WHERE CHECKED_OUT_MAPPINGS.USER_NAME IS NULL);
I have a CTE as follows
WITH details
AS ( SELECT FldId
,Rev
,Words
,row_number() OVER ( PARTITION BY FldId ORDER BY Rev DESC ) AS rn
FROM WorkItemLongTexts
WHERE ID = 2855
)
SELECT f.ReferenceName
,d.FldId
,Rev
,Words
FROM details AS d
INNER JOIN Fields AS f ON f.FldId = d.FldId
WHERE d.rn = 1 ;
The above returns the following output
ReferenceName | FldId | Rev | Words
Description 52 2 Description here
Objectives 10257 2 Objectives here
Specification 10258 6 Specification here
Requirements 10259 6 Requirements here
I want to apply PIVOT (or whatever is the best option) so that i can get output as follows
Description | Objectives | Specification | Requirements
Description here Objectives here Specification here Requirements here
Pls. suggest.
Thanks
You do this:
SELECT
FldId,
[Description],
[Objectives],
[Specification],
[Requirements]
FROM (
SELECT
ReferenceName,
FldId,
REV,
Words
FROM CTE
WHERE RowNumber = 1
) t
PIVOT (
MIN(Words)
FOR ReferenceName IN ([Description], [Objectives], [Specification], [Requirements])
) PIV
Or you can add it to your CTE, like this:
;WITH CTE2 AS (
SELECT
FldId,
REV,
[Description],
[Objectives],
[Specification],
[Requirements],
ROW_NUMBER() OVER (PARTITION BY FldId ORDER BY REV DESC) AS RowNumber
FROM TBL
PIVOT (
MIN(Words)
FOR ReferenceName IN ([Description], [Objectives], [Specification], [Requirements])
) PIV
)
SELECT
FldId,
REV,
[Description],
[Objectives],
[Specification],
[Requirements]
FROM CTE2
WHERE RowNumber = 1
WITH details
AS ( SELECT FldId
,Rev
,Words
,row_number() OVER ( PARTITION BY FldId ORDER BY Rev DESC ) AS rn
FROM WorkItemLongTexts
WHERE ID = 2855
),
cte_1
AS ( SELECT f.ReferenceName
,d.FldId
,Rev
,Words
FROM details AS d
INNER JOIN Fields AS f ON f.FldId = d.FldId
WHERE d.rn = 1
)
SELECT max(case [ReferenceName] WHEN 'Descripton' THEN [Words] ELSE NULL END) AS [Descripton]
,max(case [ReferenceName] WHEN 'Objectives' THEN [Words] ELSE NULL END) AS [Objectives]
,max(case [ReferenceName] WHEN 'Specification' THEN [Words] ELSE NULL END) AS [Specification]
,max(case [ReferenceName] WHEN 'Requirements' THEN [Words] ELSE NULL END) AS [Requirements]
FROM cte_1 ;
OR:
-- cte here as above
SELECT Description
,Objectives
,Specification
,Requirements
FROM cte_1 PIVOT ( max(Words) FOR ReferenceName IN ( Description,
Objectives,
Specification,
Requirements ) ) AS PivotTable
Do something like:
with details as (...)
, unpivotted as (select f.ReferenceName, Words
from details as d
inner join Fields as f
on f.FldId=d.FldId
where d.rn =1)
Select *
from unpivotted
pivot
(max(Words) for Description in ([Objectives],[Specification],[Requirements]) p
;