Why is Oracle REPLACE function not working for this string? - sql

We have a pattern we use all the time and this is usually pretty straightforward.
sortOrder IN VARCHAR2 := 'Title'
query VARCHAR2(32767) := q'[
SELECT
Columns
FROM tables
ORDER BY {sortOrder}
]';
query := REPLACE(query, '{sortOrder}', sortOrder);
But for this string it is not working:
WITH appl_List
AS
(
SELECT DISTINCT
appls.admin_phs_ORG_code || TO_CHAR(appls.serial_num, 'FM000000') AS core_proj_number,
appls.Appl_ID
FROM TABLE(:portfolioTable) appls
),
g1SupportingProjCount AS
(
SELECT
gen1grants.silverchair_id,
COUNT(DISTINCT al.Appl_ID) AS ApplCount
FROM
appl_List al
JOIN cg_cited_reference_gen1_grant gen1grants
ON al.core_proj_number = gen1grants.ic_serial_num
JOIN cg_cited_reference_gen1 gen1refs
ON gen1grants.silverchair_id = gen1refs.silverchair_id
GROUP BY gen1grants.Silverchair_id
),
g1SupportedPubCount AS
(
SELECT
gen1grants.silverchair_id,
COUNT(DISTINCT gen1refs.gen1_wos_uid) AS PubCount
FROM
appl_List al
JOIN cg_cited_reference_gen1_grant gen1grants
ON al.core_proj_number = gen1grants.ic_serial_num
JOIN cg_cited_reference_gen1 gen1refs
ON gen1grants.silverchair_id = gen1refs.silverchair_id
GROUP BY gen1grants.Silverchair_id
),
g2SupportingProjCount AS
(
SELECT
gen2grants.silverchair_id,
COUNT(DISTINCT al.Appl_ID) AS ApplCount
FROM
appl_List al
JOIN cg_cited_reference_gen2_grant gen2grants
ON al.core_proj_number = gen2grants.ic_serial_num
JOIN cg_cited_reference_gen2 gen2refs
ON gen2grants.silverchair_id = gen2refs.silverchair_id
GROUP BY gen2grants.Silverchair_id
),
g2SupportedPubCount AS
(
SELECT
gen2grants.silverchair_id,
COUNT(DISTINCT gen2refs.gen2_wos_uid) AS PubCount
FROM
appl_List al
JOIN cg_cited_reference_gen2_grant gen2grants
ON al.core_proj_number = gen2grants.ic_serial_num
JOIN cg_cited_reference_gen2 gen2refs
ON gen2grants.silverchair_id = gen2refs.silverchair_id
GROUP BY gen2grants.Silverchair_id
),
portfolio_cg_ids AS
(
SELECT DISTINCT md.silverchair_id
FROM
(
SELECT silverchair_id
FROM cg_cited_reference_gen1_grant gen1Grants
JOIN Appl_List appls
ON appls.core_proj_number = gen1Grants.ic_serial_num
UNION
SELECT silverchair_id
FROM cg_cited_reference_gen2_grant gen2Grants
JOIN Appl_List appls
ON appls.core_proj_number = gen2Grants.ic_serial_num
) grant_sc_ids
JOIN cg_metadata md
ON grant_sc_ids.silverchair_id = md.silverchair_id
)
SELECT
silverchairId,
TITLE,
PMID,
PMCID,
publication_year as year,
referenceCount1Gen,
supportingProjectCount1Gen,
supportedPublicationCount1Gen,
referenceCount2Gen,
supportingProjectCount2Gen,
supportedPublicationCount2Gen,
COUNT(1) OVER() as TotalCount
FROM
(
SELECT
md.SILVERCHAIR_ID silverchairId,
md.TITLE,
md.PMID,
md.PMCID ,
md.publication_year as year,
g1RefCounts.referenceCount1Gen as referenceCount1Gen,
g1SupportingProjCount.ApplCount as supportingProjectCount1Gen,
g1SupportedPubCount.PubCount as supportedPublicationCount1Gen,
g2RefCounts.referenceCount2Gen as referenceCount2Gen,
g2SupportingProjCount.ApplCount as supportingProjectCount2Gen,
g2SupportedPubCount.PubCount as supportedPublicationCount2Gen,
--COUNT(1) OVER() as TotalCount
FROM cg_metadata md
-- BEGIN datascope to current portfolio
JOIN portfolio_cg_ids
ON portfolio_cg_ids.silverchair_id = md.silverchair_id
-- END datascope to current portfolio
LEFT JOIN g1SupportingProjCount
ON g1SupportingProjCount.Silverchair_id = md.silverchair_id
LEFT JOIN g2SupportingProjCount
ON g2SupportingProjCount.Silverchair_id = md.silverchair_id
LEFT JOIN g1SupportedPubCount
ON g1SupportedPubCount.Silverchair_id = md.silverchair_id
LEFT JOIN g2SupportedPubCount
ON g2SupportedPubCount.Silverchair_id = md.silverchair_id
OUTER APPLY
(
Select Count(*) as referenceCount1Gen
FROM cg_cited_reference_gen1 g1Refs
WHERE g1Refs.silverchair_id = md.silverchair_id
) g1RefCounts
OUTER APPLY
(
Select Count(*) as referenceCount2Gen
FROM cg_cited_reference_gen2 g2Refs
WHERE g2Refs.silverchair_id = md.silverchair_id
) g2RefCounts
) results
ORDER BY {sortOrder}
Are there cases where some kind of special char in the string can keep this from working?
I'm kind of perplexed. I've been using this pattern for like 3 years and I've never had this not work.
What could be breaking this?

The query has 4000+ characters.
The text is probably being truncated somewhere down the line.

Related

simplify simple query sql

Can someone help me simplify the following query into one line .
SELECT
LL_ID,
LL_VOORNAAM,
LB_VAN_VAN,
LB_VAN_TOT,
LB_VAN_ID,
LB_VAN_INUIT_FK,
LB_NAAR_INUIT_FK,
iu_vorigeinuit_fk,
iu_id,
LB_NAAR_ID,
LB_NAAR_VAN,
LB_NAAR_TOT
FROM
LEERLING
INNER JOIN INUIT ON (LL_ID = IU_LEERLING_FK)
INNER JOIN (
SELECT
LB_ID AS LB_VAN_ID,
LB_VAN AS LB_VAN_VAN,
LB_TOT AS LB_VAN_TOT,
LB_INUIT_FK AS LB_VAN_INUIT_FK
FROM
LOOPBAAN
) AS LOOPBAAN_VAN ON (
(IU_ID = LB_VAN_INUIT_FK)
)
INNER JOIN (
SELECT
LB_ID AS LB_NAAR_ID,
LB_VAN AS LB_NAAR_VAN,
LB_TOT AS LB_NAAR_TOT,
LB_INUIT_FK AS LB_NAAR_INUIT_FK
FROM
LOOPBAAN
) AS LOOPBAAN_NAAR ON (
(iu_id = LB_NAAR_INUIT_FK)
)
WHERE
(LB_VAN_ID <> LB_NAAR_ID)
AND (
LB_NAAR_VAN = DATEADD(1 DAY TO LB_VAN_TOT)
)
and LL_ID in (41366)
order by
ll_naam
Currently, I'm getting three repeated values which I want to merge into one. See the result I would like to have.
note : "Van" means From and "naar" To
This did it for me...
) AS LOOPBAAN_VAN ON ((IU_VORIGEINUIT_FK = LB_VAN_INUIT_FK) )
SELECT
LL_ID,
LL_VOORNAAM,
LB_VAN_VAN,
LB_VAN_TOT,
LB_VAN_ID,
LB_VAN_INUIT_FK,
LB_NAAR_INUIT_FK,
iu_vorigeinuit_fk,
iu_id,
LB_NAAR_ID,
LB_NAAR_VAN,
LB_NAAR_TOT
FROM
LEERLING
INNER JOIN INUIT ON (LL_ID = IU_LEERLING_FK)
INNER JOIN (
SELECT
LB_ID AS LB_VAN_ID,
LB_VAN AS LB_VAN_VAN,
LB_TOT AS LB_VAN_TOT,
LB_INUIT_FK AS LB_VAN_INUIT_FK
FROM
LOOPBAAN
) AS LOOPBAAN_VAN ON ((IU_VORIGEINUIT_FK = LB_VAN_INUIT_FK) )
INNER JOIN (
SELECT
LB_ID AS LB_NAAR_ID,
LB_VAN AS LB_NAAR_VAN,
LB_TOT AS LB_NAAR_TOT,
LB_INUIT_FK AS LB_NAAR_INUIT_FK
FROM
LOOPBAAN
) AS LOOPBAAN_NAAR ON (( iu_id = LB_NAAR_INUIT_FK))
WHERE
(LB_VAN_ID <> LB_NAAR_ID)
AND (
LB_NAAR_VAN = DATEADD(1 DAY TO LB_VAN_TOT) )
and
LL_ID in (41366)
order by ll_naam

SQL: Missing right parenthesis in nested SELECT

My code looks like this:
...
LEFT JOIN
(
SELECT *
FROM REI_COUNTRY_CURRENCY T_CC
WHERE T_CC.AS_FROM_DATE =
(
SELECT MAX(T2_CC.AS_FROM_DATE)
FROM REI_COUNTRY_CURRENCY T2_CC
WHERE T2_CC.COUNTRY_ID = T_CC.COUNTRY_ID
) T
) CC
ON C.COUNTRY_ID = CC.COUNTRY_ID
...
I can't see why it would say "missing right parenthesis".
All parentheses are paired.
Aliases are not necessary/allowed on sub-queries:
LEFT JOIN
(
SELECT *
FROM REI_COUNTRY_CURRENCY T_CC
WHERE T_CC.AS_FROM_DATE =
(
SELECT MAX(T2_CC.AS_FROM_DATE)
FROM REI_COUNTRY_CURRENCY T2_CC
WHERE T2_CC.COUNTRY_ID = T_CC.COUNTRY_ID
) -- Remove the T from this line
) CC
ON C.COUNTRY_ID = CC.COUNTRY_ID
Or, to get rid of the correlated sub-query:
LEFT JOIN
(
SELECT *
FROM (
SELECT T_CC.*,
RANK() OVER (
PARTITION BY Country_ID
ORDER BY AS_FROM_DATE DESC
) AS rn
FROM REI_COUNTRY_CURRENCY T_CC
)
WHERE rn = 1
) CC
ON C.COUNTRY_ID = CC.COUNTRY_ID

Alternative solution for below SQL Query ,TableMasterID NOT IN take so much time

Need alternative solution for below SQL Query ,TableMasterID NOT IN take so much time, If i remove AND TableMasterID NOT IN
(SELECT DISTINCT c.TableMasterID
FROM ComFinalDataBS as C
WHERE C.ComFileID IN
(SELECT Number FROM fn_SplitInt(#ComFileID,','))) text from below query then getting result in 20 seconds otherwise result getting arround 4 minus.
SELECT A.SubTitleId,TableMasterID from SubTitle as A JOIN ComTableMaster as B ON a.SubTitle = b.TblName AND TableMasterID NOT IN (SELECT DISTINCT c.TableMasterID
FROM ComFinalDataBS as C
WHERE C.ComFileID IN
(SELECT Number FROM fn_SplitInt(#ComFileID,','))) AND B.TableMasterID IN
(SELECT DISTINCT d.TableMasterID
FROM ComData as D
WHERE D.ComFileID IN
(SELECT Number FROM fn_SplitInt(#ComFileID,','))) ORDER BY A.MainTitleID
SELECT A.SubTitleId ,
TableMasterID
FROM SubTitle AS A
JOIN ComTableMaster AS B ON A.SubTitle = B.TblName
WHERE NOT EXISTS ( SELECT 1
FROM ComFinalDataBS C
WHERE TableMasterID = C.TableMasterID
AND C.ComFileID IN (
SELECT Number
FROM MEFCampus..fn_SplitInt(#ComFileID, ',') ) )
AND NOT EXISTS ( SELECT 1
FROM ComData D
WHERE TableMasterID = D.TableMasterID
AND D.ComFileID IN (
SELECT Number
FROM MEFCampus..fn_SplitInt(#ComFileID,
',') ) )
AND B.IsDeleted = 0
ORDER BY MainTitleID
Have you tried storing the result from the fn_split_string() into an indexed temp-table first? It should help the Query Optimizer a lot.
SELECT DISTINCT Number
INTO #ComFileID
FROM dbo.fn_SplitInt(#ComFileID,',')
CREATE UNIQUE CLUSTERED INDEX uq0_ComFileID ON #ComFileID (Number) WITH (FILLFACTOR = 100)
SELECT A.SubTitleId,TableMasterID
FROM SubTitle as A
JOIN ComTableMaster as B
ON a.SubTitle = b.TblName
/*
AND B.TableMasterID NOT IN (SELECT DISTINCT c.TableMasterID
FROM ComFinalDataBS as C
JOIN #ComFileID CFI
ON CFI.Number = C.ComFileID )
*/
AND NOT EXISTS ( SELECT *
FROM ComFinalDataBS as C
JOIN #ComFileID CFI
ON CFI.Number = C.ComFileID
WHERE c.TableMasterID = B.TableMasterID )
/*
AND B.TableMasterID IN (SELECT DISTINCT d.TableMasterID
FROM ComData as D
JOIN #ComFileID CFI
ON CFI.Number = D.ComFileID
*/
AND EXISTS ( SELECT *
FROM ComData as D
JOIN #ComFileID CFI
ON CFI.Number = D.ComFileID
WHERE D.TableMasterID = B.TableMasterID )
ORDER BY A.MainTitleID

How do I group by the most recent date?

I have a HISTORY table that has multiple rows for the same record and I am trying to get the latest (closest to today's date) record. I am attempting to group by the closest date but am having a difficult time. Please check out the query below and advise me.
SELECT DISTINCT *
FROM
(SELECT etc.Complaint.Complaint_ID AS Complaint_ID
FROM etc.Complaint) AS Qry1
LEFT JOIN
(SELECT etc.Complaint.Complaint_ID AS Complaint_ID,
o.Action_User AS Resolved_User,
o.Action_Date AS LastActionDate
FROM etc.Complaint
LEFT OUTER JOIN etc.History as o
ON SUBSTRING(Primary_Key,15,LEN(Primary_Key) - 15) = etc.Complaint.Complaint_ID
AND TABLE_NAME = 'Resolution' AND o.Field_Name = 'Resolved_Ind'
AND New_Value = 1) AS Qry2
ON Qry1.Complaint_ID = Qry2.Complaint_ID
ORDER BY Qry1.Complaint_ID, MAX(Qry2.LastActionDate)
does this change help?
SELECT DISTINCT *
FROM
(SELECT etc.Complaint.Complaint_ID AS Complaint_ID FROM etc.Complaint) AS Qry1
LEFT JOIN
(SELECT etc.Complaint.Complaint_ID AS Complaint_ID,
o.Action_User AS Resolved_User,
o.Action_Date AS LastActionDate
FROM etc.Complaint
LEFT OUTER JOIN
(
SELECT SUBSTRING(Primary_Key,15,LEN(Primary_Key) - 15) as hist_Complaint_ID , MAX(Action_Date) as Action_Date
FROM etc.History
WHERE Field_Name = 'Resolved_Ind'
GROUP BY SUBSTRING(Primary_Key,15,LEN(Primary_Key) - 15)
) as o
ON o.hist_Complaint_ID = etc.Complaint.Complaint_ID
AND TABLE_NAME = 'Resolution' AND o.Field_Name = 'Resolved_Ind'
AND New_Value = 1) AS Qry2
ON Qry1.Complaint_ID = Qry2.Complaint_ID
ORDER BY Qry1.Complaint_ID, Qry2.LastActionDate
You can use ROW_NUMBER and a CTE to get it:
WITH cte AS (
SELECT etc.Complaint.Complaint_ID AS Complaint_ID,
o.Action_User AS Resolved_User,
o.Action_Date AS LastActionDate
row_number() over (partition by etc.Complaint.Complaint_ID order by o.Action_Date desc) AS rn
FROM etc.Complaint
LEFT OUTER JOIN etc.History as o
ON SUBSTRING(Primary_Key,15,LEN(Primary_Key) - 15) = etc.Complaint.Complaint_ID
AND TABLE_NAME = 'Resolution' AND o.Field_Name = 'Resolved_Ind'
AND New_Value = 1
)
SELECT * FROM cte
WHERE rn = 1

How would that be possible to make this SQL Query simpler/shorter?

It should return some fields from the SystemTable and the LoadStatus column of the latest record in the ProcessHistory table. The relationship is 1 to many:
SELECT ST.[SystemDetailID], ST.[SystemName], LH.LatestLoadStatus
FROM [SystemTable] AS ST
LEFT OUTER JOIN
(
SELECT LHInner.LoadStatus AS LatestLoadStatus, LHInner.SystemDetailID FROM [dbo].[LoadHistory] AS LHInner
WHERE LHInner.LoadHistoryID in
(
SELECT LatestLoadHisotoryID FROM
(
SELECT MAX(LoadHistoryID) as LatestLoadHisotoryID, SystemDetailID FROM [dbo].[LoadHistory]
GROUP BY SystemDetailID
) l
)
) AS LH ON ST.SystemDetailID = LH.SystemDetailID
Thanks,
This is a greatest-n-per-group query.
One Approach
SELECT ST.[SystemDetailID],
ST.[SystemName],
LH.LatestLoadStatus
FROM [SystemTable] AS ST
OUTER APPLY (SELECT TOP 1 *
FROM [dbo].[LoadHistory] LH
WHERE ST.SystemDetailID = LH.SystemDetailID
ORDER BY LoadHistoryID DESC) LH
You can also use row_number
WITH LH
AS (SELECT *,
ROW_NUMBER() OVER (PARTITION BY SystemDetailID
ORDER BY LoadHistoryID DESC) RN
FROM [dbo].[LoadHistory])
SELECT ST.[SystemDetailID],
ST.[SystemName],
LH.LatestLoadStatus
FROM [SystemTable] AS ST
LEFT JOIN LH
ON LH.SystemDetailID = ST.SystemDetailID
AND LH.RN = 1
SELECT ST.[SystemDetailID], ST.[SystemName], LH.LatestLoadStatus
FROM [SystemTable] AS ST
INNER JOIN [dbo].[LoadHistory] AS LH
ON ST.SystemDetailID = LH.SystemDetailID
AND LH.LoadHistoryID IN
(SELECT MAX(LoadHistoryID) as LoadHistoryID
FROM [dbo].[LoadHistory]
GROUP BY SystemDetailID )