PORTING FROM DB2 TO ORACLE - ORA-00907: missing right parenthesis - sql

I'm getting the error " ORA-00907: missing right parenthesis" at row: 7, column: 6
when I launch this query on ORACLE 11g DB:
SELECT B.ID_COND AS IDCOND,B.ID_PAYMENT AS IDPAYMENT, B.DT_SCAD AS DATASCAD, B.DT_PAYMENT AS DATAPAYMENT,B.DE_CHANNELPAG AS CHANNELPAYMENT, B.DT_STARTVALID AS DATASTART, B.DT_ENDVALID AS DATAEND,
B.IM_TOTAL AS TOTAL, B.ST_PAYMENT AS STATECOND, B.CO_CIP AS codCIP, B.ID_PEND AS IDPEND, B.TI_PAYMENT AS TIPOPAYMENT,
B.cause_PAYMENT AS causaleCOND, B.IM_PAYMENT AS amountPAYMENT, B.DE_MIDDLEPAYMENT AS MIDDLEPAYMENT, B.DE_NOTEPAYMENT as notePAYMENT,
(select st_PAYMENT from QLT.paymnts P
where P.ID_COND=B.ID_COND
AND ROWNUM <= 1
order by (CASE WHEN P.st_PAYMENT='ES' THEN 1 ELSE 0 END) DESC, TS_INSMNT DESC
) AS STATEPAYMENT
FROM QLT.JLTCOPD B
WHERE B.ID_PEND = '269' AND B.TI_PAYMENT = 'S'
ORDER BY B.DT_SCAD ASC, DT_STARTVALID ASC
Trying to delete this row: 'order by (CASE WHEN P.st_PAYMENT='ES' THEN 1 ELSE 0 END) DESC, TS_INSMNT DESC' no errors are shown and a result is returned.
I'm trying to convert a DB2 query to ORACLE, the original DB2 inner query was:
(select st_PAYMENT from QLT.paymnts P where P.ID_COND=B.ID_COND order by (CASE WHEN P.st_PAYMENT='ES' THEN 1 ELSE 0 END) DESC, TS_INSMNT DESC fetch first 1 rows only)
How can I change it in order to do the porting without errors?

try replacing the inner query with:
(
select st_PAYMENT FROM
(
select st_PAYMENT from QLT.paymnts P
where P.ID_COND=B.ID_COND
order by (CASE WHEN P.st_PAYMENT='ES' THEN 1 ELSE 0 END) DESC, TS_INSMNT DESC
)
WHERE ROWNUM <= 1
)

Related

How to use CASE WHEN in FIRST_VALUE Oracle

If I case when then select it by first_value saparately then it works, but it I combine First_value(case when ....) then it not work althought the code still run without syntax error
My try, I want to find latest overdue date, it only show null
FIRST_VALUE(
CASE
WHEN inv.aging_period = 0
AND is_tad_paid = 0
AND is_mad_paid = 0
AND inv.min_amount_due > 0 THEN
inv.due_date
ELSE
NULL
END
)
OVER(PARTITION BY inv.account_id
ORDER BY inv.DUE_DATE DESC NULLS LAST
) AS latest_overdue_date,
If I try this saparately, it works:
select sub.*, first_value(ALL_OVER_DUE_DAY) over (partition by account_id order by ALL_OVER_DUE_DAY desc nulls last) as latest_over_due2
from (select
CASE
WHEN inv.aging_period = 0
AND is_tad_paid = 0
AND is_mad_paid = 0
AND inv.min_amount_due > 0 THEN
inv.due_date
ELSE
NULL
END AS ALL_OVER_DUE_DAY from t1 ) SUB
sample data, my resul column is the last column
Replace First_value with MAX(), add unbounded preceeding... like bellow
max(
CASE
WHEN inv.aging_period = 0
AND is_tad_paid = 0
AND is_mad_paid = 0
AND inv.min_amount_due > 0 THEN
inv.due_date
ELSE
NULL
END
)
OVER(PARTITION BY inv.account_id
ORDER BY inv.DUE_DATE DESC NULLS LAST
ROWS BETWEEN
UNBOUNDED PRECEDING
AND
UNBOUNDED following
)

Hive query to find conversion ratio

I am trying this query in Hive and it's not working.
select
(
(
select
count(*)
from
click_streaming
where
page_id= 'e7bc5fb2-1231-11eb-adc1-0242ac120002'
and is_page_view = 'Yes'
) / (
select
count(*)
from
click_streaming
where
button_id= 'fcba68aa-1231-11eb-adc1-0242ac120002'
and is_button_click= 'Yes'
)
) as conversion_ratio;
Error I am getting: cannot recognize input near 'select' 'count' '(' in expression specification
I am basically trying to get conversion rate of customers who view the page and click the button to book a cab.
This is not how the syntax can be. Just join them both or use a case when to do your job.
select
sum(case when page_id= 'e7bc5fb2-1231-11eb-adc1-0242ac120002' and is_page_view = 'Yes' then 1 else 0 end) /
sum(case when button_id= 'fcba68aa-1231-11eb-adc1-0242ac120002' and is_button_click= 'Yes' then 1 else 0 end) conv_ratio
FROM
click_streaming
or you can reuse your SQLs but you got to join them
select c1/c2
from (
select
count(*) c1
from
click_streaming
where
page_id= 'e7bc5fb2-1231-11eb-adc1-0242ac120002'
and is_page_view = 'Yes') rs
join (select
count(*) c2
from
click_streaming
where
button_id= 'fcba68aa-1231-11eb-adc1-0242ac120002'
and is_button_click= 'Yes')rs2

SQL Server 2008 equivalent for FETCH OFFSET with WHERE clause

I have a program with which my users can look up all the data traffic that happend the last 7 days. I use a stored procedure to get me that data - 250 records at a time (the user can page through that). The problem was, that the users get a lot of timeouts when they wanted to see that data.
Here is the stored procedure before I tried to optimize ist.
#MaxRecCount INT,
#PageOffset INT,
#IncludeData BIT
SELECT [Client], [Schema], [Version], [Records], [Fetched], [Receipted], [ProvidedAt], [FetchedAt], [ReceiptedAt],[PacketIds], [Record] FROM (
SELECT TOP(#MaxRecCount) MAX(bai_ExportPendingArchive.[UserName]) AS Client,
MAX(bai_ExportPendingArchive.Category) AS [Schema],
MAX(bai_ExportPendingArchive.ContractVersion) AS [Version],
COUNT(*) AS [Records],
SUM (CASE WHEN bai_ExportPendingAckArchive.ExportPendingId IS NULL THEN 0 ELSE 1 END) as [Fetched],
SUM (CASE WHEN bai_ExportPendingAckArchive.Receipted IS NULL THEN 0 ELSE 1 END) as [Receipted],
MAX(bai_ExportArchive.Inserted) AS [ProvidedAt],
MAX(CASE WHEN bai_ExportPendingAckArchive.ExportPendingId IS NULL THEN NULL ELSE bai_ExportPendingAckArchive.Inserted END) AS [FetchedAt],
MAX(CASE WHEN bai_ExportPendingAckArchive.Receipted IS NULL THEN NULL ELSE bai_ExportPendingAckArchive.Receipted END) AS [ReceiptedAt],
bai_ExportArchive.PacketIds AS [PacketIds],
NULL AS [Record],
ROW_NUMBER() Over (Order By MAX(bai_ExportArchive.Inserted) desc) as [RowNumber]
FROM bai_ExportArchive
INNER JOIN bai_ExportPendingArchive ON bai_ExportArchive.Id = bai_ExportPendingArchive.ExportId
LEFT OUTER JOIN bai_ExportPendingAckArchive ON bai_ExportPendingAckArchive.ExportPendingId = bai_ExportPendingArchive.Id
GROUP BY bai_ExportPendingArchive.[UserName], bai_ExportArchive.PacketIds, bai_ExportPendingArchive.Category
) AS InnerTable WHERE RowNumber > (#PageOffset * #MaxRecCount) and RowNumber <= (#PageOffset * #MaxRecCount + #MaxRecCount)
ORDER BY RowNumber
#MaxRecCount, #PageOffset and #IncludeData are parameter which came from my C#-method.
This version needed about 1:35min to get me the data I wanted. To make the stored procedure faster I insered a WHERE clause to filter for the Inserted col (also I made an Index on this column) and to use OFFSET FETCH:
The stored procedure after the optimization:
#MaxRecCount INT,
#PageOffset INT,
#IncludeData BIT
Declare #pageStart int
Declare #pageEnd int
SET #pageStart = #PageOffset * #MaxRecCount
SET #pageEnd = #pageStart + #MaxRecCount + 50
IF #IncludeData = 0
BEGIN
SELECT [Client], [Schema], [Version], [Records], [Fetched], [Receipted], [ProvidedAt], [FetchedAt], [ReceiptedAt],[PacketIds], [Record] FROM (
SELECT TOP(#MaxRecCount) bai_ExportPendingArchive.[UserName] AS Client,
bai_ExportPendingArchive.Category AS [Schema],
MAX(bai_ExportPendingArchive.ContractVersion) AS [Version],
COUNT(*) AS [Records],
SUM (CASE WHEN bai_ExportPendingAckArchive.ExportPendingId IS NULL THEN 0 ELSE 1 END) as [Fetched],
SUM (CASE WHEN bai_ExportPendingAckArchive.Receipted IS NULL THEN 0 ELSE 1 END) as [Receipted],
MAX(bai_ExportArchive.Inserted) AS [ProvidedAt],
MAX(CASE WHEN bai_ExportPendingAckArchive.ExportPendingId IS NULL THEN NULL ELSE bai_ExportPendingAckArchive.Inserted END) AS [FetchedAt],
MAX(CASE WHEN bai_ExportPendingAckArchive.Receipted IS NULL THEN NULL ELSE bai_ExportPendingAckArchive.Receipted END) AS [ReceiptedAt],
bai_ExportArchive.PacketIds AS [PacketIds],
NULL AS [Record],
ROW_NUMBER() Over (Order By MAX(bai_ExportArchive.Inserted) desc) as [RowNumber]
FROM bai_ExportArchive
INNER JOIN bai_ExportPendingArchive ON bai_ExportArchive.Id = bai_ExportPendingArchive.ExportId
LEFT OUTER JOIN bai_ExportPendingAckArchive ON bai_ExportPendingAckArchive.ExportPendingId = bai_ExportPendingArchive.Id
Where bai_ExportArchive.Inserted <= (Select bai_ExportArchive.Inserted from bai_ExportArchive Order by bai_ExportArchive.Inserted DESC Offset #pageStart ROWS FETCH NEXT 1 ROWS Only)
And bai_ExportArchive.Inserted > (Select bai_ExportArchive.Inserted from bai_ExportArchive Order by bai_ExportArchive.Inserted DESC Offset #pageEnd ROWS FETCH NEXT 1 ROWS Only)
GROUP BY bai_ExportPendingArchive.[UserName], bai_ExportArchive.PacketIds, bai_ExportPendingArchive.Category
) AS InnerTable
ORDER BY RowNumber
This version gives me the data in about 2s. The only problem is, I work on Microsoft SQL Server 2014 BUT my Users use SQL Server 2008+. The Problem now is, that the OFFSET FETCH dosn't work in Server 2008. And now I'm clueless how I can optimize my stored procedure that it is fast and work on SQl Server 2008.
I'm thankful for any help :)
Try this method to handle the pagination in SQL Server 2005/2008.
First use a CTE for your select query with a ROW_NUMBER() column to identify the record number/count. After that you can select a range of records from this CTE using your PAGE_NUMBER and PAGE_COUNT. Example is below
DECLARE #P_PAGE_NUM INT = 0
,#P_PAGE_SIZE INT = 20
;WITH CTE
AS
( /*SELECT ROW_NUMBER() OVER (ORDER BY COL_to_SORT DESC) AS [ROW_NO]
,...
WHERE ....
*/ -- You can replace your select query here, but column [ROW_NO] should be there in your select list.
--ie ROW_NUMBER() OVER (ORDER BY put_column-to-sort-here DESC) AS [ROW_NO]
)
SELECT *
--,( SELECT COUNT(*) FROM CTE) AS [TOTAL_ROW_COUNT]
FROM CTE
WHERE (
ISNULL(#P_PAGE_NUM,0) = 0 OR
[ROW_NO] BETWEEN ( #P_PAGE_NUM - 1) * #P_PAGE_SIZE + 1
AND #P_PAGE_NUM * #P_PAGE_SIZE
)
ORDER BY [ROW_NO]

Sql server aggregate function and GROUP BY Clause error

I have a query below where it compares the number of stagingCabincrew and StagingCockpitCrew columns from the staging schema and compares them to their data schema equivalent 'DataCabinCrew' and 'DataCockpitCrew'.
Below is the query and the results outputted:
WITH CTE AS
(SELECT cd.*,
c.*,
DataFlight,
l.ScheduledDepartureDate,
l.ScheduledDepartureAirport
FROM
(SELECT *,
ROW_NUMBER() OVER(PARTITION BY LegKey
ORDER BY UpdateID DESC) AS RowNumber
FROM Data.Crew) c
INNER JOIN Data.CrewDetail cd ON c.UpdateID = cd.CrewUpdateID
AND cd.IsPassive = 1
AND RowNumber = 1
INNER JOIN
(SELECT *,
Carrier + CAST(FlightNumber AS VARCHAR) + Suffix AS DataFlight
FROM Data.Leg) l ON c.LegKey = l.LegKey )
SELECT StagingFlight,
sac.DepartureDate,
sac.DepartureAirport,
cte.DataFlight,
cte.ScheduledDepartureDate,
cte.ScheduledDepartureAirport,
SUM(CASE
WHEN sac.CREWTYPE = 'F' THEN 1
ELSE 0
END) AS StagingCabinCrew,
SUM(CASE
WHEN sac.CREWTYPE = 'C' THEN 1
ELSE 0
END) AS StagingCockpitCrew,
SUM(CASE
WHEN cte.CrewType = 'F' THEN 1
ELSE 0
END) AS DataCabinCrew,
SUM(CASE
WHEN cte.CrewType = 'C' THEN 1
ELSE 0
END) AS DataCockpitCrew
FROM
(SELECT *,
Airline + CAST(FlightNumber AS VARCHAR) + Suffix AS StagingFlight,
ROW_NUMBER() OVER(PARTITION BY Airline + CAST(FlightNumber AS VARCHAR) + Suffix
ORDER BY UpdateId DESC) AS StageRowNumber
FROM Staging.SabreAssignedCrew) sac
LEFT JOIN CTE cte ON StagingFlight = DataFlight
AND sac.DepartureDate = cte.ScheduledDepartureDate
AND sac.DepartureAirport = cte.ScheduledDepartureAirport
AND sac.CREWTYPE = cte.CrewType
WHERE MONTH(sac.DepartureDate) + YEAR(sac.DepartureDate) = MONTH(GETDATE()) + YEAR(GETDATE())
AND StageRowNumber = 1 --AND cte.ScheduledDepartureDate IS NOT NULL
--AND cte.ScheduledDepartureAirport IS NOT NULL
GROUP BY StagingFlight,
sac.DepartureDate,
sac.DepartureAirport,
cte.DataFlight,
cte.ScheduledDepartureDate,
cte.ScheduledDepartureAirport
The results are correct, all I need to do is add a condition in the WHERE clause where StagingCabinCrew <> DataCabinCrew AND StagingCockpitCrew <> DataCockpitCrew
If a row appears then we have found an error in the data, I just need helping adding this condition in the WHERE Clause because the columns in the WHERE Clause are referring to a SUM and CASE Function. I just need help manipulating the query so that I can add this WHERE Clause
I will guess you are trying to use an alias in the same query.
You CANT do this, because the alias wont be recognized in the WHERE.
SELECT field1 + field2 as myField
FROM yourTable
WHERE myField > 3
You need to include it in a sub query
with cte2 as (
SELECT field1 + field2 as myField
FROM yourTable
)
SELECT *
FROM cte2
WHERE myField > 3
or repeat the function
SELECT field1 + field2 as myField
FROM yourTable
WHERE field1 + field2 > 3

Getting a sum of only the first instance of a column in a sql query

I have the following SQL code:
SELECT EmployeeID,
SUM(CASE
WHEN Error1 = '0'
THEN 1
ELSE 0
END + CASE
WHEN Error2 = '0'
THEN 1
ELSE 0
END + CASE
WHEN Error3 = '0'
THEN 1
ELSE 0
END) AS TotalErrors
FROM SubmittedDocuments
GROUP BY EmployeeID
The statement should calculate the number of errors in the table for each employee. However, there is another column in the table SubmittedDocuments named "DocumentName". How could I write a statement that only counts errors for the first instance of each DocumentName? (Or only counts for the one with the lowest "SubmittedID", the unique identifier)
Sorry if anything in unclear, I will attempt to clear up any confusion in the comments.
I might have not got this right from your question, but I think this should work. If you could show some sample data and expected output then we can definitely have a sure answer.
SELECT EmployeeID
SUM(CASE WHEN DocIDErr > 1 THEN 0 ELSE 1 END)
FROM
(SELECT EmployeeID
, Error1
, ROW_NUMBER() OVER (PARTITION BY EmployeeID ORDER BY DocumentName) AS DocIDErr
FROM SubmittedDocuments) AS RS
GROUP BY EmployeeID
I don't think you want aggregation. I think you just want to select the first document for each name.
If so, this may be what you want:
select sd.*,
((case when error1 = '0' then 1 else 0 end) +
(case when error2 = '0' then 1 else 0 end) +
(case when error3 = '0' then 1 else 0 end)
) as numerrors
from (select sd.*,
row_number() over (partition by documentname order by submittedid) as seqnum
from SumittedDocuments sd
) sd
where seqnum = 1;