How to group substrings in Teradata 14? - teradata

I have the following table in Teradata 14 , I am not allowed to write procedures and functions myself, but i can use strtok, strtok_split_to_table etc
id property
1 1234X (Yel), 2225Y (Red), 1234X (Gre),
2
3 1222Y (Pin),
4 1134E (Yel), 4565Y (Whi), 1134E (Red), 2222Y (Red),
How can I group the above table so that each object would have all attributes listed in one brackets
id property
1 1234X (Yel Gre), 2225Y (Red),
2
3 1222Y (Pin ),
4 1134E (Yel Red), 4565Y (Whi), 2222Y (Red),
The property code is always a 5 character string, e.g. 1222Y . The color code is always 3 character , e.g. Pin
I tried using this solution but got an error A column or character expression is larger than max size
In addition I tried strtok_split_to_table and was able to create a modified table, but do not how to proceed from that

Why do you store denormalized data in a RDBMS and then process it to create even worse denormalized output?
Modifying my solution from the link you posted to utilize STRTOK_SPLIT_TO_TABLE instead of recursion:
SELECT
id,
MAX(CASE WHEN newpos = 1 AND newgrp <> '(),' THEN newgrp ELSE '' END) ||
MAX(CASE WHEN newpos = 2 THEN newgrp ELSE '' END) ||
MAX(CASE WHEN newpos = 3 THEN newgrp ELSE '' END) ||
MAX(CASE WHEN newpos = 4 THEN newgrp ELSE '' END) ||
MAX(CASE WHEN newpos = 5 THEN newgrp ELSE '' END) ||
MAX(CASE WHEN newpos = 6 THEN newgrp ELSE '' END)
-- add as many CASEs as needed
FROM
(
SELECT
id,
ROW_NUMBER()
OVER (PARTITION BY id
ORDER BY newgrp) AS newpos,
TRIM(a || ' (' ||
MAX(CASE WHEN tokennum = 1 THEN b || ' ' ELSE '' END) ||
MAX(CASE WHEN tokennum = 2 THEN b || ' ' ELSE '' END) ||
MAX(CASE WHEN tokennum = 3 THEN b || ' ' ELSE '' END) ||
MAX(CASE WHEN tokennum = 4 THEN b || ' ' ELSE '' END) ||
MAX(CASE WHEN tokennum = 5 THEN b || ' ' ELSE '' END) ||
MAX(CASE WHEN tokennum = 6 THEN b || ' ' ELSE '' END)
-- add as many CASEs as needd
) || '), ' AS newgrp
FROM
(
SELECT
id, tokennum,
TRIM(SUBSTRING(token FROM 1 FOR POSITION('(' IN TRIM(token)||'(') - 1)) AS a,
TRIM(TRAILING ')' FROM SUBSTRING(token FROM POSITION('(' IN token) + 1)) AS b
FROM
TABLE( STRTOK_SPLIT_TO_TABLE(vt.id, vt.property, ',')
RETURNS (id INT,
tokennum INT,
token VARCHAR(30) CHARACTER SET UNICODE
)
) AS dt
) AS dt
GROUP BY id, a
) AS dt
GROUP BY id;
If you got access to the TDStats.udfconcat function it can be further simplified (but there's way to control the order of properties:
SELECT id,
CASE
WHEN TRIM(TDStats.udfconcat(' ' || a || ' ' || b)) || ',' <> '(),'
THEN TRIM(TDStats.udfconcat(' ' || a || ' ' || b)) || ','
ELSE ''
END
FROM
(
SELECT
id,
TRIM(SUBSTRING(token FROM 1 FOR POSITION('(' IN TRIM(token)||'(') - 1)) AS a,
'('|| OTRANSLATE(TDStats.udfconcat(TRIM(TRAILING ')' FROM SUBSTRING(token FROM POSITION('(' IN token) + 1))), ',', ' ') || ')'AS b
FROM
TABLE( STRTOK_SPLIT_TO_TABLE(vt.id, vt.property, ',')
RETURNS (id INT,
tokennum INT,
token VARCHAR(30) CHARACTER SET UNICODE
)
) AS dt
GROUP BY id, a
) AS dt
GROUP BY id;
Most of the work was fiddling with the spaces and commas in the right place to get the requested output.
Still i would never store data as such in a RDBMS.

Try this , I had slightly modified dnoeths query from your post
WITH RECURSIVE cte
(id,
len,
remaining,
word,
pos
) AS (
SELECT
id,
POSITION(',' IN property || ',') - 1 AS len,
SUBSTRING(property || ',' FROM len + 2) AS remaining,
TRIM(SUBSTRING(property FROM 1 FOR len)) AS word,
1
FROM TableA
UNION ALL
SELECT
id,
POSITION(',' IN remaining)- 1 AS len_new,
SUBSTRING(remaining FROM len_new + 2),
TRIM(SUBSTRING(remaining FROM 1 FOR len_new)),
pos + 1
FROM cte
WHERE remaining <> ''
)
SELECT
id,
MAX(CASE WHEN newpos = 1 THEN newgrp ELSE '' END) ||
MAX(CASE WHEN newpos = 2 THEN newgrp ELSE '' END) ||
MAX(CASE WHEN newpos = 3 THEN newgrp ELSE '' END) ||
MAX(CASE WHEN newpos = 4 THEN newgrp ELSE '' END) ||
MAX(CASE WHEN newpos = 5 THEN newgrp ELSE '' END) ||
MAX(CASE WHEN newpos = 6 THEN newgrp ELSE '' END)
-- add as many CASEs as needed
FROM
(
SELECT
id,
ROW_NUMBER()
OVER (PARTITION BY id
ORDER BY newgrp) AS newpos,
a ||
MAX(CASE WHEN pos = 1 THEN '(' || b ELSE '' END) ||
MAX(CASE WHEN pos = 2 THEN ' ' || b ELSE '' END) ||
MAX(CASE WHEN pos = 3 THEN ' ' || b ELSE '' END) ||
MAX(CASE WHEN pos = 4 THEN ' ' || b ELSE '' END) ||
MAX(CASE WHEN pos = 5 THEN ' ' || b ELSE '' END) ||
MAX(CASE WHEN pos = 6 THEN ' ' || b ELSE '' END)
-- add as many CASEs as needed
|| '), ' AS newgrp
FROM
(
SELECT
id,
ROW_NUMBER()
OVER (PARTITION BY id, a
ORDER BY pos) AS pos,
SUBSTRING(word FROM 1 FOR POSITION('(' IN word) - 1) AS a,
TRIM(TRAILING ')' FROM SUBSTRING(word FROM POSITION('(' IN word) + 1)) AS b
FROM cte
WHERE word <> ''
) AS dt
GROUP BY id, a
) AS dt
GROUP BY id
UNION ALL
SELECT id,property FROM TableA WHERE property IS NULL OR TRIM(property)=' ';

Related

CASE WHEN THEN resolving to zeros in SQLite

I am using SQLite inside my .NET application and I have the following query:
select (CASE IFNULL(CCODE_1, '') when 'STD' then '_' else '' end) +
(CASE IFNULL(CFRRR_CS, '') when '1' then 'F_' when '2' then 'R_' when '3' then 'FR_' else '' end) +
IFNULL(CCODE_1, '') +
(CASE when (IFNULL(CCODE_2, '') = '') then '' else '_' end) +
IFNULL(CCODE_2, '') +
(CASE when (IFNULL(CCODE_3, '') = '') then '' else '_' end) +
IFNULL(CCODE_3, '') as OptionID
from X20_TIRES
The query above produces a single OptionID column of all 0s. Nothing else.
And here is some sample data from X20_TIRES:
I am expecting results such as the following:
R_F41A
R_F41V
etc...
It's clear to me that the case/when/then is breaking down and simply spitting out 0s, but I cannot understand why. What am I doing wrong?
If you want to concatenate all these results from the CASE statements,
you must use the || operator instead of +:
select
(CASE IFNULL(CCODE_1, '') when 'STD' then '_' else '' end) ||
(CASE IFNULL(CFRRR_CS, '') when '1' then 'F_' when '2' then 'R_' when '3' then 'FR_' else '' end) ||
IFNULL(CCODE_1, '') ||
(CASE when (IFNULL(CCODE_2, '') = '') then '' else '_' end) ||
IFNULL(CCODE_2, '') ||
(CASE when (IFNULL(CCODE_3, '') = '') then '' else '_' end) ||
IFNULL(CCODE_3, '') as OptionID
from X20_TIRES

PL-SQL - ORA-00932: inconsistent datatypes: expected DATE got NUMBER

Trying to loop through a sysrefcursor but getting ORA-00932 seems like when looping, the dates, e.g.: 1990/01/01 get operated on as if they were a division ?
set serveroutput on;
DECLARE
email VARCHAR2(1000);
webcastEngagement NUMBER(10,1);
videoEngagement NUMBER(10,1);
documentEngagement NUMBER(10,1);
totalEngagement NUMBER(10,1);
--averageEngagement NUMBER(4,1);
totalWebcastSeconds NUMBER(10);
engagementMinutes NUMBER(10, 1);
last30DaysEM NUMBER(10, 1);
last60DaysEM NUMBER(10, 1);
fromDate DATE;
engagementPrediction NUMBER(10);
engagementLevel VARCHAR2(6 CHAR);
totalWebcasts NUMBER(10);
totalVideos NUMBER(10);
totalDocuments NUMBER(10);
totalURLs NUMBER(10);
firstName VARCHAR2(1000);
lastName VARCHAR2(1000);
company VARCHAR2(1000);
jobTitle VARCHAR2(1000);
workPhone VARCHAR2(1000);
clientName VARCHAR2(1000);
portalEnabled VARCHAR2(5);
resources NUMBER(10);
videoProfile NUMBER;
showInterestCloud VARCHAR2(10);
attended VARCHAR(1);
leadIndex NUMBER := 1;
clientFunnelStages VARCHAR2(4000);
funnelStage VARCHAR2(100 CHAR);
partnerref VARCHAR2(4000);
experienceProfileId NUMBER := 525;
resp ON24MASTER.WEBCAST_REPORTS.ResultSetCursor;
BEGIN
resp := WEBCAST_REPORTS.LEAD_BASIC_INFO('testqa_11071113#inbfw.com',22917);
LOOP
FETCH resp into email, webcastEngagement,videoEngagement,documentEngagement, totalEngagement,totalWebcastSeconds,engagementMinutes,last30DaysEM,last60DaysEM,
fromDate,-- also tried to_date(fromDate, 'YYYY-MM-DD')
engagementPrediction,engagementLevel,totalWebcasts, totalVideos, totalDocuments, totalURLs, firstName,lastName,company, jobTitle,workPhone,
clientName,portalEnabled,resources,videoProfile,showInterestCloud,attended,leadIndex,clientFunnelStages,funnelStage,partnerref,experienceProfileId;
dbms_output.put_line(email|| ' ---- ' || webcastEngagement|| ' ---- ' ||videoEngagement|| ' ---- ' ||documentEngagement|| ' ---- ' || totalEngagement|| ' ---- ' ||totalWebcastSeconds|| ' ---- ' ||engagementMinutes|| ' ---- ' ||last30DaysEM|| ' ---- ' ||last60DaysEM|| ' ---- ' ||fromDate|| ' ---- ' ||
engagementPrediction|| ' ---- ' ||engagementLevel|| ' ---- ' ||totalWebcasts|| ' ---- ' || totalVideos|| ' ---- ' || totalDocuments|| ' ---- ' || totalURLs|| ' ---- ' || firstName|| ' ---- ' ||lastName|| ' ---- ' ||company|| ' ---- ' || jobTitle|| ' ---- ' ||workPhone|| ' ---- ' ||
clientName|| ' ---- ' ||portalEnabled|| ' ---- ' ||resources|| ' ---- ' ||videoProfile|| ' ---- ' ||showInterestCloud|| ' ---- ' ||attended|| ' ---- ' ||leadIndex|| ' ---- ' ||clientFunnelStages|| ' ---- ' ||funnelStage|| ' ---- ' ||partnerref|| ' ---- ' ||experienceProfileId);
exit when resp%notfound;
END LOOP;
CLOSE resp;
END;
/
in function body, fromDate DATE does very simple things, it will be assigned similar to: fromDate := SYSDATE - 60
My goal is to output the result set.
What currently works, has horrible output:
variable rc refcursor;
DECLARE
LEADEMAIL VARCHAR2(200);
CLIENTID NUMBER;
BEGIN
LEADEMAIL := 'nunyo#business.com';
CLIENTID := 22921;
:rc := WEBCAST_REPORTS.LEAD_BASIC_INFO(
LEADEMAIL => LEADEMAIL,
CLIENTID => CLIENTID
);
END;
/
print rc;
This is part of the output:
EMAIL CLIENT_ID
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------
CLIENT_NAME CG_ACTIVE WEBCAST_ENGAGEMENT VIDEO_ENGAGEMENT DOCUMENT_ENGAGEMENT TOTAL_ENGAGEMENT AVG_WEBCAST_MINUTES NGAGEMENT_MINUTES TOTAL_WEBCASTS
TOTAL_VIDEOS TOTAL_DOCUMENTS TOTAL_URLS A PREDIC LAST_30D_ENGAGEMENT_MINUTES LAST_60D_ENGAGEMENT_MINUTES ENGAGEMENT_LEVEL FIRST_NAME
------------ --------------- ---------- - ------ --------------------------- --------------------------- -------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
LAST_NAME
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
JOB_TITLE
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
WORK_PHONE
COMPANY REGISTRATION_SOURCE H H H H RESOURCES S
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------- - - - - ---------- -
FUNNEL_STAGE
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0 0 0 Y HIGH 34 34 LOW test
EMAIL CLIENT_ID
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------
CLIENT_NAME
Update
FUNCTION LEAD_BASIC_INFO(
leadEmail VARCHAR2,
clientId NUMBER
) RETURN ResultSetCursor IS
-- rest of the variables
-- more code
OPEN resultSet FOR
select
nvl(email, leadEmail) EMAIL,
clientId CLIENT_ID,
clientName CLIENT_NAME,
portalEnabled CG_ACTIVE,
nvl(webcastEngagement, 0) WEBCAST_ENGAGEMENT,
nvl(videoEngagement, 0) VIDEO_ENGAGEMENT,
nvl(documentEngagement, 0) DOCUMENT_ENGAGEMENT,
nvl(totalEngagement, 0) TOTAL_ENGAGEMENT,
--nvl(averageEngagement, 0) AVERAGE_ENGAGEMENT,
case when nvl(totalWebcasts, 0) = 0
then 0
else nvl(round((totalWebcastSeconds/totalWebcasts)/60, 1), 0)
end AVG_WEBCAST_MINUTES,
nvl(engagementMinutes, 0) ENGAGEMENT_MINUTES,
nvl(totalWebcasts, 0) TOTAL_WEBCASTS,
nvl(totalVideos, 0) TOTAL_VIDEOS,
nvl(totalDocuments, 0) TOTAL_DOCUMENTS,
nvl(totalURLs, 0) TOTAL_URLS,
case when (nvl(totalWebcasts, 0) + nvl(totalVideos, 0) + nvl(totalDocuments, 0) + nvl(totalURLs, 0) > 0) then 'Y' else 'N' end ATTENDED,
case engagementPrediction when 1 then 'LOW' when 2 then 'MEDIUM' when 3 then 'HIGH' else '' end as PREDICTIVE_ENGAGEMENT,
last30DaysEM as LAST_30D_ENGAGEMENT_MINUTES,
last60DaysEM as LAST_60D_ENGAGEMENT_MINUTES,
engagementLevel as ENGAGEMENT_LEVEL,
nvl(firstName, '') FIRST_NAME,
nvl(lastName, '') LAST_NAME,
nvl(jobTitle, '') JOB_TITLE,
nvl(workPhone, '') WORK_PHONE,
nvl(company, '') COMPANY,
nvl(partnerref, '') REGISTRATION_SOURCE,
case when (length(trim(firstName)) > 0 or length(trim(lastName)) > 0)
then 'Y'
else 'N'
end HAS_NAME,
case when (length(trim(jobTitle)) > 0)
then 'Y'
else 'N'
end HAS_JOB_TITLE,
case when (length(trim(workPhone)) > 0)
then 'Y'
else 'N'
end HAS_WORK_PHONE,
case when (length(trim(company)) > 0)
then 'Y'
else 'N'
end HAS_COMPANY,
nvl(resources, 0) RESOURCES,
case when (lower(showInterestCloud) = 'yes')
then 'Y'
else 'N'
end SHOW_BIS,
funnelStage FUNNEL_STAGE
from dual;
RETURN resultSet;
END LEAD_BASIC_INFO;
Your `fetch into is expecting a date in the 10th column:
FETCH resp into email, -- 1
webcastEngagement, -- 2
videoEngagement, -- 3
documentEngagement, -- 4
totalEngagement, -- 5
totalWebcastSeconds, -- 6
engagementMinutes, -- 7
last30DaysEM, -- 8
last60DaysEM, -- 9
fromDate, -- 10
...
The 10th column in your function's query is a number:
OPEN resultSet FOR
select
nvl(email, leadEmail) EMAIL, -- 1
clientId CLIENT_ID, -- 2
clientName CLIENT_NAME, -- 3
portalEnabled CG_ACTIVE, -- 4
nvl(webcastEngagement, 0) WEBCAST_ENGAGEMENT, -- 5
nvl(videoEngagement, 0) VIDEO_ENGAGEMENT, -- 6
nvl(documentEngagement, 0) DOCUMENT_ENGAGEMENT, -- 7
nvl(totalEngagement, 0) TOTAL_ENGAGEMENT, -- 8
--nvl(averageEngagement, 0) AVERAGE_ENGAGEMENT,
case when nvl(totalWebcasts, 0) = 0
then 0
else nvl(round((totalWebcastSeconds/totalWebcasts)/60, 1), 0)
end AVG_WEBCAST_MINUTES, -- 9
nvl(engagementMinutes, 0) ENGAGEMENT_MINUTES, -- 10
...
The two lists of columns/variables seem to be in completely different orders. For instance, WEBCAST_ENGAGEMENT is the fifth column in your query, but second in your fetch.
Fetch is positional - it doesn't matter what the result set columns are called (or if they are aliased at all), you have to fetch them into the variables in the same order they appear in the query's select list.
You don't actually seem to have any date columns in your query, called fromDate or anything else.
So, you are trying to fetch the number supplied in the query's 10th column, the nvl() that's aliased as ENGAGEMENT_MINUTES, into the date variable fromDate. Hence the error - expected DATE (because that's how fromDate is declared) got NUMBER (because that's what ENGAGEMENT_MINUTES is).

How to get column like results to single string with separator

I have a silly problem which I'm not able to solve in Teradata.
I have n tables and for each of n tables (n>1000) I have to get the table's columns, which can differ from table to table.
My question is: how can I get the result from one query (something like Select columnName from dbc.columns where tablename = table1) in a string, let's say _vColumns, in order to be able to use later on the value in that sorting (_vColumns) in a dynamical SQL syntax?
I did that long ago using dbc.columns
/*** Rows to concatenated string ***/
/*** Nested version instead of hundreds of CASEs.
Returns a single concatenated string consisting of up to 2048
columnnames ***/
SELECT
databasename
,tablename
,max(case when rnk mod 16 = 0 then ColumnName else '' end) ||
max(case when rnk mod 16 = 1 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 2 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 3 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 4 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 5 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 6 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 7 then ',' || ColumnName else '' end)
as Columns
from
(
sel
databasename
,tablename
,rnk / 16 as rnk
,max(case when rnk mod 16 = 0 then ColumnName else '' end) ||
max(case when rnk mod 16 = 1 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 2 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 3 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 4 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 5 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 6 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 7 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 8 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 9 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 10 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 11 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 12 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 13 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 14 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 15 then ',' || ColumnName else '' end) as ColumnName
from
(
select
databasename
,tablename
,rnk / 16 as rnk
,max(case when rnk mod 16 = 0 then ColumnName else '' end) ||
max(case when rnk mod 16 = 1 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 2 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 3 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 4 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 5 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 6 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 7 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 8 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 9 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 10 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 11 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 12 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 13 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 14 then ',' || ColumnName else '' end) ||
max(case when rnk mod 16 = 15 then ',' || ColumnName else '' end) as ColumnName
from
(
select
databasename
,tablename
,trim(columnName) as ColumnName
,rank() over (partition by databasename, tablename
order by columnid) -1 as rnk
from
dbc.columns
) dt
group by 1,2,3
)dt
group by 1,2,3
)dt
group by 1,2
But, since Td14.10 you should use dbc.ColumnV instead (if you got any column name longer than 30 characters) and then 2048*128 characters will hit the maximum limit of 64000 characters...

Tuning Oracle SQL having NOT EXIST clause

I want to tune below query eliminating NOT EXIST clause specified in it. Can you please help.
GLT_temp_upload is temporary table where as DA_DUEDATE is partitioned table having huge data in it.
Please help
SELECT DISTINCT
batchid,
store_area,
STORE_AREA
|| ','
|| STORE_ID
|| ','
|| SMS_ID
|| ','
|| SMS_SERVICE
|| ','
|| SYNERGY_MODE_ID
|| ','
|| FREQUENCY
|| ','
|| DUEDATE
|| ','
|| STUDY_ID
|| ','
|| YEAR
|| ''
|| WEEK_ID
||',Not exist in Da_Duedate'
FROM GLT_temp_upload upload
WHERE upload.batchid = 1
AND NOT EXISTS
(SELECT due.week_id,
due.country_id,
due.year,
due.study_id,
due.store_id,
due.store_area,
due.synergy_mode_id,
upload.batchid,
due.due_date,
upload.sms_service
FROM DA_DUEDATE due
WHERE due.store_id = upload.store_id
AND due.study_id = upload.study_id
AND due.store_area = upload.store_area
AND due.frequency = upload.frequency
AND due.sms_service = upload.sms_service
AND due.week_id = upload.week_id
AND due.country_id = upload.country_id
AND due.year = upload.year
AND due.sms_id = upload.sms_id
AND due.synergy_mode_id =
upload.synergy_mode_id)
You may try NOT EXISTS / LEFT JOIN / NOT IN
In your NOT EXISTS it's enough to SELECT 1 instead of the list of columns
Sometimes LEFT JOIN can be more beneficial (depending on indexes, the size of the tables etc)
SELECT DISTINCT
batchid,
store_area,
STORE_AREA
|| ','
|| STORE_ID
|| ','
|| SMS_ID
|| ','
|| SMS_SERVICE
|| ','
|| SYNERGY_MODE_ID
|| ','
|| FREQUENCY
|| ','
|| DUEDATE
|| ','
|| STUDY_ID
|| ','
|| YEAR
|| ''
|| WEEK_ID
||',Not exist in Da_Duedate'
FROM GLT_temp_upload upload left join DA_DUEDATE due
ON due.store_id = upload.store_id
AND due.study_id = upload.study_id
AND due.store_area = upload.store_area
AND due.frequency = upload.frequency
AND due.sms_service = upload.sms_service
AND due.week_id = upload.week_id
AND due.country_id = upload.country_id
AND due.year = upload.year
AND due.sms_id = upload.sms_id
AND due.synergy_mode_id = upload.synergy_mode_id
WHERE upload.batchid = 1 and due.store_id is NULL;
I'd recommend you looking at the execution plan to find an optimal solution for your case.

How can i add extra columns to my select statement using with clause

How can add V_SP_CDRA_WEEKLY_UPDATE.indication column to following sql statement. As of now it is displaying only str_out column. any help will be appreciated.
with
transformation(str_in,flag,str_out) as
(select substr(s,instr(s,'href=') + 5),1,cast(substr(s,1,instr(s,'href=') + 4) as varchar2(4000))
from (select KEY_DOCUMENTS s From V_SP_CDRA_WEEKLY_UPDATE Where KEY_DOCUMENTS like '%%https:%%')
union all
select substr(str_in,2),
case when flag = 1
and substr(str_in,1,1) != '>'
then 1
when substr(str_in,1,1) = '>'
then 0
when substr(str_in,1,5) = 'href='
then 1
else 0
end,
str_out || case when substr(str_in,1,1) = ' '
and flag = 1
then '%20'
else substr(str_in,1,1)
end
from transformation
where length(str_in) > 0
)
select str_out
from transformation
where str_in is null;
I don't know your data, so I try to ask your question:
with
transformation(str_in, flag, str_out, indication) as
(select substr(s,instr(s,'href=') + 5),
1,
cast(substr(s,1,instr(s,'href=') + 4) as varchar2(4000)),
i
from (select KEY_DOCUMENTS s, indication i
From V_SP_CDRA_WEEKLY_UPDATE
Where KEY_DOCUMENTS like '%%https:%%')
union all
select substr(str_in,2),
case when flag = 1 and substr(str_in,1,1) != '>'
then 1
when substr(str_in,1,1) = '>'
then 0
when substr(str_in,1,5) = 'href='
then 1
else 0
end,
str_out || case when substr(str_in,1,1) = ' ' and flag = 1
then '%20'
else substr(str_in,1,1)
end,
null as i
from transformation
where length(str_in) > 0)
select str_out, indication
from transformation
where str_in is null;

Resources