Unable to CREATE OR REPLACE VIEW with Databricks using CTE's - azure-databricks

I am trying to create a view in Databricks using the WITH method in Databricks with my SQL code.
However, I'm getting the error:
Error in SQL statement: ParseException:
mismatched input '<EOF>' expecting {'(', 'UP_TO_DATE', 'AS', 'COMMENT', 'PARTITIONED', 'TBLPROPERTIES'}(line 1, pos 65)
== SQL ==
CREATE OR REPLACE VIEW curorigination.opportunitiespresentationV3
-----------------------------------------------------------------^^^
The full code is:
CREATE OR REPLACE VIEW curorigination.opportunitiespresentationV3
AS
; WITH numbering AS (
SELECT CompanyOwner, CurrentOpportunityStatus, LastDateStatusChanged,
rank() OVER (PARTITION BY CompanyOwner, CurrentOpportunityStatus ORDER BY LastDateStatusChanged DESC) AS rank
FROM enrorigination.opportunities_hv
)
SELECT CompanyOwner,
CASE CurrentOpportunityStatus WHEN 'Action - 1. Analysing' THEN LastDateStatusChanged END AS `Action - 1. Analysing`,
CASE CurrentOpportunityStatus WHEN 'Action - 2. Trying to meet' THEN LastDateStatusChanged END AS `Action - 2. Trying to meet`,
CASE CurrentOpportunityStatus WHEN 'Action - 3. Date agreed' THEN LastDateStatusChanged END AS `Action - 3. Date agreed`,
CASE CurrentOpportunityStatus WHEN 'Action - 4. Post meeting' THEN LastDateStatusChanged END AS `Action - 4. Post meeting`,
CASE CurrentOpportunityStatus WHEN 'Action - 5. Chopped' THEN LastDateStatusChanged END AS `Action - 5. Chopped`
FROM numbering
WHERE rank = 1
ORDER BY CompanyOwner, CurrentOpportunityStatus, LastDateStatusChanged
Any thoughts on why I'm unable to create a view?
Sample Data Set
CREATE TABLE temptable4 (
CurrentOpportunityStatus nvarchar(50),
LastDateStatusChanged date,
CompanyOwner nvarchar(50),
OpportunityDescription nvarchar(max),
CreatedOn datetime2,
OpportunityName nvarchar(100))
INSERT temptable4 VALUES
(N'Tip - Anticipated',CONVERT(DATETIME, '2022-03-11', 120),N'',N'cc',CONVERT(DATETIME2, '2022-03-11 09:17:02.0000000', 121),N'CC ''22'),
(N'Deal - Won',CONVERT(DATETIME, '2022-03-10', 120),N'Edward Shuckburgh',N'Flagged by Frank L in Frankfurt. CDK is the leading provider of Dealer Management Systems (DMS) to the automotive industry globally. Frank recently met with Patrick Katenkamp (former CEO of Incadea, a competitor to CDK) who mentioned that CDK may be open to carving-out their UK business. CDK is predominantly US focussed and is understood to be considering what to do with its international businesses. Unclear on size of the UK operation, but it may be worth reaching out to better understand the company''s situation. DM first met Neil Packham via an intro from HIEC in Feb 2020.',CONVERT(DATETIME2, '2018-05-24 10:55:00.0000000', 121),N'CDKI ''18'),
(N'Deal - WIP',CONVERT(DATETIME, '2022-03-08', 120),N'Sophie Hoas',N'Allegedly at 40mn USD business providing on-line training for the US bar and UK professional legal exams. Better positioned to cope with the proposed changes in training regime in the UK.',CONVERT(DATETIME2, '2020-11-24 12:48:53.0000000', 121),N'barbri ''20'),
(N'Deal - Won',CONVERT(DATETIME, '2022-03-08', 120),N'Nicole Dixson',N'G3 / Good Governance Group is a strategic advisory consultancy which specialises in providing advice on risk mitigation, governance, cyber security and regulatory compliance. Described as a \"mini Hakluyt\" and doing £12-15m EBITDA. Reputational concerns about clients, and likely people heavy - chop.',CONVERT(DATETIME2, '2021-11-05 08:47:16.0000000', 121),N'G3 ''21'),
(N'Deal - Won',CONVERT(DATETIME, '2022-03-04', 120),N'Christoph Leitner-Dietmaier',N'Battery-backed roll-up of ERP businesses. They have now changed management (based in the UK, former CEO and CFO of CoreHR) and started to unify previously disparate operations. €150m revenues and €40m EBITDA. Something could happen over next 6-12 months according to Nomura
25-Oct-21 CLD: Arma mandated, Paul G mentioned that they will intro 5 parties to management pre-Xmas for process launch in the NY.',CONVERT(DATETIME2, '2021-08-03 13:33:58.0000000', 121),N'Forterro ''21'),
(N'Tip - Anticipated',CONVERT(DATETIME, '2022-03-04', 120),N'',N'Test Opportunity',CONVERT(DATETIME2, '2022-03-04 12:35:53.0000000', 121),N'19 Entertainment ''22'),
(N'Tip - Anticipated',CONVERT(DATETIME, '2022-03-04', 120),N'',N'test',CONVERT(DATETIME2, '2022-03-04 12:40:23.0000000', 121),N'123.ie ''22'),
(N'Deal - Won',CONVERT(DATETIME, '2022-03-03', 120),N'Geeta Hirani',N'Bryan Garnier mandate \"Project Goldeneye\", this is a specialist diagnosic microscope scanner business based in Finland. Allegedly making €9m EBITDA (up from 1), growing strongly. To look into. Tip from DM.',CONVERT(DATETIME2, '2021-12-16 11:12:06.0000000', 121),N'Grundium ''21'),
(N'Deal - WIP',CONVERT(DATETIME, '2022-03-02', 120),N'James Cann',N'Description',CONVERT(DATETIME2, '2022-03-02 10:31:52.0000000', 121),N'JC training'),
(N'Action - 1. Analysing',CONVERT(DATETIME, '2022-02-07', 120),N'Geeta Hirani',N'Market-leading Nordic HR tech platform focused primarily on recruitment (c.80% of ARR), onboarding and talent management. Pure-play SaaS business with c. €20m of ARR. Created by a merger of three smaller companies by Verdane who invested in 2018. Houlihan Lokey (GCA Altium) has been mandated to run a narrow sales process as Verdane can no longer fund further M&A due to fund concentration limits. We know the CEO from Visma where he was in the Finance Director of the Enterprise Division. Potential target for EMM.',CONVERT(DATETIME2, '2021-12-15 11:25:53.0000000', 121),N'Talentech ''21'),
(N'Action - 5. Chopped',CONVERT(DATETIME, '2022-02-02', 120),N'Catherine Parry',N'hhh',CONVERT(DATETIME2, '2021-12-21 12:23:41.0000000', 121),N'JC Opp test 2'),
(N'Tip - Anticipated',CONVERT(DATETIME, '2022-02-02', 120),N'',N'Test Opportunity for new EMM product',CONVERT(DATETIME2, '2022-02-02 16:28:05.0000000', 121),N'Test Opportunity ''22'),
(N'Tip - Anticipated',CONVERT(DATETIME, '2022-02-02', 120),N'',N'test opportunity',CONVERT(DATETIME2, '2022-02-02 17:16:23.0000000', 121),N'New Test Opportunity ''22'),
(N'Deal - Won',CONVERT(DATETIME, '2021-12-21', 120),N'James Cann',N'Opp',CONVERT(DATETIME2, '2021-12-21 11:18:07.0000000', 121),N'JC Opp Reg Test'),
(N'Action - 5. Chopped',CONVERT(DATETIME, '2021-12-16', 120),N'Frank Löhner',N'With our fully digitized RegTech and Capital Markets Tech solutions, our state-of-the-art technologies and in-depth knowledge of capital markets we develop your digital future.
I hope the above sample data works

Try this instead , you can build a nested case statement rather than your implementation , however if your intention is towards a pivot structure do , let me know , I ll update the answere accordingly
CREATE OR REPLACE VIEW curorigination.opportunitiespresentationV3
AS
WITH numbering AS (
SELECT CompanyOwner, CurrentOpportunityStatus, LastDateStatusChanged,
rank() OVER (PARTITION BY CompanyOwner, CurrentOpportunityStatus ORDER BY LastDateStatusChanged DESC) AS rank
FROM enrorigination.opportunities_hv
)
SELECT CompanyOwner,
CASE
WHEN CurrentOpportunityStatus = 'Action - 1. Analysing' THEN LastDateStatusChanged
WHEN CurrentOpportunityStatus = 'Action - 2. Trying to meet' THEN LastDateStatusChanged
WHEN CurrentOpportunityStatus = 'Action - 3. Date agreed' THEN LastDateStatusChanged
WHEN CurrentOpportunityStatus = 'Action - 4. Post meeting' THEN LastDateStatusChanged
WHEN CurrentOpportunityStatus = 'Action - 5. Chopped' THEN LastDateStatusChanged
END AS CurrentOpportunityStatus,
LastDateStatusChanged
FROM numbering
WHERE rank = 1
ORDER BY CompanyOwner, CurrentOpportunityStatus, LastDateStatusChanged
;

Related

Calculate Business Days between two Dates Oracle Rightnow

I am working in Oracle RightNow and I was using the below to calculate the Workdays between two dates but with the new year, the logic seems to no longer work. This would be the code used in a custom report column for a client.
((DATE_DIFF(sysdate(),incidents.created)/86400) + 1) - ((to_number(date_format(sysdate(),'WW')) - to_number(date_format(incidents.created,'WW')))* 2) - IF(Date_format(incidents.created,'DAY') = 'Sunday',1,0) - IF(Date_format(sysdate(),'DAY') = 'Saturday',1,0)
Is there different code I could use to accomplish this without it breaking with a new new year?
Thanks,
B
You can use this Oracle answer:
SELECT ( TRUNC( SYSDATE, 'IW' ) - TRUNC( created, 'IW' ) ) * 5 / 7
+ LEAST( SYSDATE - TRUNC( SYSDATE, 'IW' ) + 1, 5 )
- LEAST( created - TRUNC( created, 'IW' ) + 1, 5 )
AS WeekDaysDifference
FROM incidents;
Which, for the sample data:
CREATE TABLE incidents ( created ) AS
SELECT DATE '2020-12-31' FROM DUAL UNION ALL
SELECT DATE '2021-01-01' FROM DUAL UNION ALL
SELECT SYSDATE FROM DUAL
Outputs:
| WEEKDAYSDIFFERENCE |
| ---------------------------------------: |
| 2.83034722222222222222222222222222222222 |
| 1.83034722222222222222222222222222222222 |
| 0 |
db<>fiddle here
Looking at the Oracle RightNow CRM documentation, you can convert the Oracle solution to:
DATE_DIFF(
DATE_TRUNC( SYSDATE(), 'IWEEKS' ),
DATE_TRUNC( incidents.created, 'IWEEKS' )
) / 86400 * 5 / 7
+
IF (
DATE_DIFF(SYSDATE(), DATE_TRUNC(SYSDATE(), 'IWEEKS')) / 86400 < 5,
DATE_DIFF(SYSDATE(), DATE_TRUNC(SYSDATE(), 'IWEEKS')) / 86400,
5
)
-
IF (
DATE_DIFF(incidents.created, DATE_TRUNC(incidents.created, 'IWEEKS')) / 86400 < 5,
DATE_DIFF(incidents.created, DATE_TRUNC(incidents.created, 'IWEEKS')) / 86400,
5
)
(Note: I do not have access to an Oracle RightNow environment so the conversion is untested and based solely on the documentation and there may be errors or possible improvements; however, it is hopefully sufficient to give you the solution.)
Oracle B2C Service (F.K.A. RightNow) doesn't use Oracle DB currently. And, the syntax for the analytics tool is unique to the application, not the underlying DB. So, the suggestions regarding a SQL-based solution won't work.
Your logic appears to be impacted by your use of the transformation of dates using WW in the date_format function, which is the week number for the date in the first parameter of the function. This resets to 1 at the new year, which is why you're likely getting the behavior that you are; you're not accounting for the significance of multiple years in the equation.
Does the organization that you built the report for have working hours setup in B2C Service? If so, then you might be able to simplify your formula with rel_date_diff, which might handle some of the weekday/weekend logic for you. You could try to "brute force" the equation with a date_diff, then calculate the weeks of the diff, then multiply that times 5 workdays per week. But, you'll get anomalies based on what you consider to be the first day of the week and when the report is run. Use the documentation to find appropriate functions to help you.
The last option, but one that will work in the event you cannot develop an equation using the out-of-the-box functions in analytics, is to build an analytics report extension. Your custom code for the extension could implement the date processing logic however you require (in C# for the .NET console and JavaScript for the BUI -- hopefully your client has moved to BUI).

Consolidate rows

I'm trying to cut down on rows a report has. There are 2 assets that return on this query but I want them to show up on one row.
Basically if dc.name LIKE '%CT/PT%' then I want it to be same row as the asset. The SP.SVC_PT_ID is the common field to join them.
There will be times when there is no dc.name LIKE '%CT/PT%' however I still want the DV.MFG_SERIAL_NUM to populated just with a Null to the right.
Select SP.SVC_PT_ID, SP.DEVICE_ID, DV.MFG_SERIAL_NUM, dc.name,
substr(dc.name,26)
From EIP.SVC_PT_DEVICE_REL SP,
eip.device_class dc,
EIP.DEVICE DV
Where SP.EFF_START_TIME < To_date('20170930', 'YYYYMMDD') + 1
and SP.EFF_END_TIME is null
and dc.id = DV.device_class_id
and DV.ID = SP.device_id
ORDER BY SP.SVC_PT_ID, DV.MFG_SERIAL_NUM;
I'm not sure I understand what you are saying; test case would certainly help. You said that query you posted returns two rows (only if we saw which ones ...) but you want them to be displayed as the image you attached to the message.
Generally speaking, you can do that using an aggregate function (such as MAX) on certain column(s), along with the GROUP BY clause that contains the rest of them.
Just for example:
select svc_pt_id, max(ctpt_name) ctpt_name, sum(ctpt_multipler) ctpt_multipler
from ...
group by svc_pt_id
As I said: a test case would help people who'd want to answer the question. True - someone might have understood it far better than I did and will provide assistance nevertheless.
EDIT: after you posted sample data (which, by the way, don't match screenshot you posted previously), maybe something like this might do the job: use analytic function to check whether name contains CT/PT; if so, take its data. Otherwise, display both rows.
SQL> with test as (
2 select 14 svc_pt_id, 446733 device_id, 'Generic Electric' name from dual union
3 select 14, 456517, 'Generic CT/PT, Multiplier' from dual
4 ),
5 podaci as
6 (select svc_pt_id, device_id, name,
7 rank() over (partition by svc_pt_id
8 order by case when instr(name, 'CT/PT') > 1 then 1
9 else 2
10 end) rnk
11 from test
12 )
13 select svc_pt_id, device_id, name
14 from podaci
15 where rnk = 1;
SVC_PT_ID DEVICE_ID NAME
---------- ---------- -------------------------
14 456517 Generic CT/PT, Multiplier
SQL>
My TEST table (created by WITH factoring clause) would be the result of your current query.

How to add one month to month and year

I am working in oracle and new to coding and new to this site so I apologize in advance for the newbie question:
I have a script I am trying to run that will return the sum of next months' sales orders and compare that figure against our budgeted sales forecast. It was working great last month (November) when I set it up but now that it's December, I believe it's having problems figuring out that next month is a new year.
Essentially I just want to sum of our sales order records from the next month and compare that number against our forecast number.
Here is what I have so far (I'm sure I am making lots of grammatical mistakes so please be patient!)
select
"Backlog", "Forecast Amount" , round("Backlog"/"Forecast Amount",4) as "Backlog Percent"
from
(select round(sum(NVL(unit_price,0) *NVL( ship_quan,0)),2) as "Backlog"
from v_backlog_releases
where
(TO_CHAR(V_BACKLOG_RELEASES.PROMISE_DATE,'MM\YYYY') = TO_CHAR(sysdate,'MM\YYYY')+1)),
(select budamount as "Forecast Amount"
from
glbudget,
glperiods
where
glbudget.glperiods_id=glperiods.id and
TO_CHAR(GLPERIODS.START_DATE,'MM') = TO_CHAR(sysdate,'MM')+1)
The system won't let me post images of the output since I am too new. Essentially I should get something that looks like this:
Backlog | Forecast Amount | Backlog Percent
100,000 | 200,000 | .50
The backlog column is just a sum of ship quantities * price for all orders due to ship the following month.
Your issue is that for December TO_CHAR(sysdate, 'MM') + 1 is returning 13 instead of 1 of the next year. Obviously there is no month 13...
Try using ADD_MONTHS(sysdate, 1) instead and handle that result as appropriate. Best advice is to handle dates as dates instead of chars whenever possible.
Update based on comments:
Try using:
EXTRACT(MONTH FROM GLPERIODS.START_DATE) = EXTRACT(MONTH FROM ADD_MONTHS(sysdate, 1))
Documentation: https://docs.oracle.com/cd/B14117_01/server.101/b10759/functions045.htm

Show report horizontally with SQL or PL/SQL

I am developing a report which should display the data horizontally.
What must be shown is the following:
email#1.com 12/09/2013 11/09/2013 10/09/2013 09/09/2013...
email#2.com 22/03/2013 21/03/2013 12/02/2013 02/01/2013...
Well, I have these data organized in two tables:
Member and Report.
The Member table has the email address and the Report table has dates, and each email can have many different dates.
I can easily retrieve that information vertically:
SELECT M.EMAIL, R.LAST_OPEN_DATE
FROM MEMBER M, REPORT R
WHERE M.MEMBER_ID = R.MEMBER_ID
AND R.STATUS = 1
AND TRUNC(R.LAST_OPEN_DATE) >= TRUNC(SYSDATE) - 120;
However to show the results horizontally is complicated, anyone have a tip or know how I can do this?
I'm using Oracle 11g.
You can get the dates into columns with pivot:
SELECT *
FROM (
SELECT M.EMAIL, R.LAST_OPEN_DATE,
ROW_NUMBER() OVER (PARTITION BY M.MEMBER_ID
ORDER BY R.LAST_OPEN_DATE DESC) AS RN
FROM MEMBER M, REPORT R
WHERE M.MEMBER_ID = R.MEMBER_ID
AND R.STATUS = 1
AND TRUNC(R.LAST_OPEN_DATE) >= TRUNC(SYSDATE) - 120
)
PIVOT (MIN(LAST_OPEN_DATE) FOR (RN) IN (1, 2, 3, 4, 5, 6, 7, 8));
SQL Fiddle.
Essentially this is assigning a number to each report date for each member, and then the pivot is based on that ranking number.
But you'd need to have each of the possible number of days listed; if you can have up to 240 report dates, the PIVOT IN clause would need to be every number up to 240, i.e. IN (1, 2, 3, ..., 239, 240), not just up to eight as in that Fiddle.
If you ever had a member with more than 240 dates you wouldn't see some of them, so whatever high number you pick would have to be high enough to cover every possibility, now and in the foreseeable future. As your query is limited to 120 days, even 240 seems quite high, but perhaps you have more than one per day - in which case there is no real upper limit.
You could potentially have to format each date column individually, but hopefully your reporting layer is taking care of that.
If you just wanted to perform string aggregation using the multiple dates for each email, in you could do this in 11g:
SELECT M.EMAIL,
LISTAGG(TO_CHAR(R.LAST_OPEN_DATE, 'DD/MM/YYYY'), ' ')
WITHIN GROUP (ORDER BY R.LAST_OPEN_DATE DESC)
FROM MEMBER M, REPORT R
WHERE M.MEMBER_ID = R.MEMBER_ID
AND R.STATUS = 1
AND TRUNC(R.LAST_OPEN_DATE) >= TRUNC(SYSDATE) - 120
GROUP BY M.EMAIL;
EMAIL DATES
-------------------- -------------------------------------------
email#1.com 12/04/2014 11/04/2014 10/04/2014 09/04/2014
email#2.com 12/05/2014 02/04/2014 22/03/2014 21/03/2014
SQL Fiddle.
Which is OK for a text report, but not if this query is feeding into a reporting tool.
First of all, number of columns in a query is determined before hand and can't be adjusted by the data. To overcome that, you might be interested in dynamic query
But, in simple static case, you will need to use PIVOT construction.
As a first step, you will need to assign rows to the columns
select EMAIL, row_number() over (partition by email order by last_date) col
from yourtable
then you add "magic" PIVOT:
<your query>
PIVOT
(
max(last_date)
for col in (1, 2, 3, ..., 240)
)

How to sort specific Hierarchy Level in OLAP (SSAS) via MDX

I'm using SSAS OLAP and I want to apply sorting of the levels of a hierarchy.
I know that I can sort the whole hierarchy via ORDER function (I have some issues when I'm trying to apply DESC sorting on the whole hierarchy), but what I really want to achieve is sorting of a specific level. For example in the [Date].[Calendar] hierarchy (Adventure Works Cube), I want to have ASC sorting of years, DESC sorting of Quarter, ASC sorting of Months, etc.
I do not want to break the hierarchy (using BASC or BDESC), I just need them sorted on the same level. Do you have an idea if this is possible at all, as I was unable to find anything simillar?
What you can do is crossjoining the ordered correspoding attribute hierarchies. Could you verify the results of the following:
select
[Measures].[Internet Sales Amount] on 0,
Order(
[Date].[Calendar Year].[Calendar Year].MEMBERS,
[Measures].[Internet Sales Amount]
,ASC)
*
Order(
[Date].[Calendar Quarter of Year].[Calendar Quarter of Year].MEMBERS,
[Measures].[Internet Sales Amount]
,DESC)
*
Order(
[Date].[Calendar].[Month].MEMBERS,
[Measures].[Internet Sales Amount]
,ASC)
ON 1
from [Adventure Works]
Including the all members could help ([Date].[Calendar Year] instead of [Date].[Calendar Year] in case of the first crossjoin set)
Philip,
The following is a working solution, if not a really nice one:
WITH MEMBER Measures.[year] as
[Date].[Calendar].CurrentMember.Properties('Key0', typed)
MEMBER Measures.[qtr or mth] as
[Date].[Calendar].CurrentMember.Properties('Key1', typed)
MEMBER Measures.[sortKey] as
CASE
WHEN [Date].[Calendar].CurrentMember.Level IS [Date].[Calendar].[Calendar Year] THEN
Measures.[year] * 1000
WHEN [Date].[Calendar].CurrentMember.Level IS [Date].[Calendar].[Calendar Quarter] THEN
Measures.[year] * 1000 + (5 - Measures.[qtr or mth]) * 100
ELSE // month
Measures.[year] * 1000 + (4 - Int((Measures.[qtr or mth] - 1) / 3)) * 100 + Measures.[qtr or mth]
END
SELECT {Measures.[year], Measures.[qtr or mth], Measures.[sortKey]}
ON COLUMNS,
Order(
[Date].[Calendar].[Calendar Year]
+
[Date].[Calendar].[Calendar Quarter]
+
[Date].[Calendar].[Month]
,
Measures.[sortKey]
,BASC
)
ON ROWS
FROM [Adventure Works]
The measures on the columns are just for clarification how it works. And the main logic is in the generation of the sortKey measure which generates an integer key as follows: four digits for the year, one digit for the backwards quarter (Q4 -> 1, ... Q1 -> 4), two digits for the month. Then, using that, it is straightforward to call Order to return the sorted set.
It turned out that it is impossible to achieve the desired effect - there's no such MDX query that can sort different levels with different sorting type. More information is available in this thread.

Resources