Calculated member shows all members including where facts do not exist - ssas

I have created a calculated member that assigns customer type. The problem is that it shows every single member from customer dimension and I have too little experience to fix it.
I want to show only customers that actualy ordered.
e.g. [Measures].[Total Amount]>0
for currently selected period. e.g. current year. ([Basic Calendar].[Year - Week - Date])
Please advise and see formula below.
CREATE MEMBER CURRENTCUBE.[Measures].[Customer Type]
AS IIF( [Measures].[Orders by Customer]=0, "Zero Customer",
IIF( [Measures].[Orders by Customer]=1, "One Off Customer",
IIF([Measures].[Orders by Customer]>1 and [Measures].[Orders by Customer]<4 , "2 to 3 Orders",
IIF([Measures].[Orders by Customer]>3 and [Measures].[Orders by Customer]<6, "4 to 5 Orders",
IIF([Measures].[Orders by Customer]>5, "VIP Customer", "Other"))))),
VISIBLE = 1 ;
Many thanks

Just add an 'empty' condition that returns null:
CREATE MEMBER CURRENTCUBE.[Measures].[Customer Type]
AS
IIF( IsEmpty([Measures].[Orders by Customer]), null,
IIF([Measures].[Orders by Customer]=0, "Zero Customer",
IIF( [Measures].[Orders by Customer]=1, "One Off Customer",
IIF([Measures].[Orders by Customer]>1 and [Measures].[Orders by Customer]<4 , "2 to 3 Orders",
IIF([Measures].[Orders by Customer]>3 and [Measures].[Orders by Customer]<6, "4 to 5 Orders",
IIF([Measures].[Orders by Customer]>5, "VIP Customer", "Other")))))),
VISIBLE = 1 ;

Related

How to add 2nd price column in SQL when info is normally stored on 2 separate rows

I currently have a very simple SQL script, which provides the sell price for a special customer of ours, who gets Priceline "J". I'd like to add a column of Retail pricing as well for them to reference, which is normally Priceline "R". My query currently looks like this:
SELECT RS_PCL.SKU,
RS_PCL.SKU_DESC,
RS_PCL.PACKAGE,
RS_PCL.PRICE AS [Sell Price],
RS_PCL.STD AS [Start Date],
RS_PCL.END AS [End Date]
FROM RS_PCL
WHERE RS_PCL.PRICELINE = "J"
Would anyone be able to help me figure out how I could add the "R" price line as another column instead of separate rows?
I can add WHERE RS_PCL.PRICELINE IN ("J","R") but it would create a separate row for each Retail price, instead of in the column next to it. I've seen examples of a separate SELECT CASE WHEN, but not sure exactly how the syntax works.
The prices are always going to have the same start date, so it would just need to join where the SKU matches and the Start Date matches.
NOTE : IM sorry I accidentally edited your answer, not my question...
Revised: Running into errors with this code still, saying "Your query does not include the specified expression 'GL Type' as part of an aggregate function" or would say each field that isn't included in the group by clause
SELECT RS_PCL.[GL Type],
RS_PCL.SKU,
RS_PCL.[SKU Desc],
RS_PCL.Supplier,
RS_PCL.[Case UPC],
RS_PCL.[Pack UPC],
RS_PCL.[Unit UPC],
RS_PCL.PDCN,
RS_PCL.Package,
RS_PCL.[Price Start Date],
RS_PCL.[Price End Date],
Iif( RS_PCL.PRICELINE = "J" , RS_PCL.Price , Null) AS [Sell Price],
Iif( RS_PCL.PRICELINE = "R" , RS_PCL.Price , Null) AS [Retail Price],
RS_PCL.Cost,
RS_PCL.Tax,
RS_PCL.Freight
FROM RS_PCL
WHERE (RS_PCL.PRICELINE IN ("J","R"))
Tested the Self Join query listed below, I keep getting a "Syntax Error in FROM Clause" with this query.
SELECT J.*, R.R_PRICE FROM RS_PCL AS J
INNER JOIN SELECT (RS_PCL.SKU, RS_PCL.[Price Start Date], RS_PCL.Price AS R_PRICE FROM RS_PCL WHERE RS_PCL.PRICELINE = "R") AS R
ON J.SKU = R.SKU AND J.[Price Start Date] = R.[Price Start Date]
WHERE RS_PCL.Priceline = "J"
SELECT CASE does not work in Access query. Use IIf() or Switch() or Choose().
Perhaps a CROSSTAB query or emulate CROSSTAB with expressions to create fields. Presuming, as indicated in question title, there is one "J" and one "R" record for each data combination:
SELECT SKU, SKU_DESC, PACKAGE, STD, END,
Max(IIf(PRICELINE = "J", PRICE, Null)) AS J,
Max(IIf(PRICELINE = "R", PRICE, Null)) AS R
FROM RS_PCL
GROUP BY SKU, SKU_DESC, PACKAGE, STD, END
Or a self-join, assuming only fields needed as unique identifier are SKU and STD:
SELECT J.*, R.R_PRICE FROM RS_PCL AS J
INNER JOIN (SELECT SKU, STD, PRICE AS R_PRICE FROM RS_PCL WHERE PRICELINE = "R") AS R
ON J.SKU = R.SKU AND J.STD = R.STD
WHERE PRICELINE = "J";
This would be useful on a report but useless for a data entry form.
Yet another approach would use DLookup() domain aggregate function. Domain aggregate function can cause slow performance in query or form but the dataset would be editable.

Error in SQL Server CTE statement

I believe I'm writing this CTE wrong, I'm a major novice with this so explain as much as you can. Still getting the can not be bound error on almost everything
Error messages:
The multi part identifier could not be bound "PS_Margin.Emp or Vendor ID
The multi part identifier could not be bound "PS_Margin.Project Profit by Person %
Issues/ Goals:
Possible need to add aliases to column names with spaces and special characters although I don't know how to do this
WITH
Profit_Score_CTE ( [Emp or Vendor ID], [Project Profit by Person %] ) AS (
SELECT PS_Margin.[Emp or Vendor ID],
CASE
WHEN ps.[Project Profit by Person %] > .4 THEN 1
WHEN ps.[Project Profit by Person %] > .2 THEN 3
WHEN ps.[Project Profit by Person %] > .1 THEN 5
WHEN ps.[Project Profit by Person %] > .05 THEN 8
ELSE 13 END
AS [Profit Score]
FROM dbo.PS_Margin AS ps
)
SELECT emp.[Employee Name], emp.[USID], [Profit Score]*0.3 AS [Final Score]
FROM dbo.PS_Emp AS emp
left join Profit_Score_CTE
ON emp.USID = Profit_Score_CTE.[Emp or Vendor ID]
"Cannot be bound" usually refers to how you are ID'ing columns with a table alias. Try giving your table an alias and using that for the columns:
WITH
--Section 1: Profit Score
Profit_Score_CTE( [Emp or Vendor ID], [Project Profit by Person %] ) AS (
SELECT PS_Margin.[Emp or Vendor ID],
CASE
WHEN ps.[Project Profit by Person %] > .4 THEN 1
WHEN ps.[Project Profit by Person %] > .2 THEN 3
WHEN ps.[Project Profit by Person %] > .1 THEN 5
WHEN ps.[Project Profit by Person %] > .05 THEN 8
ELSE 13 END
AS [Profit Score]
FROM [dbo].[PS_Margin] ps
)
I'm guessing because you haven't provided enough information to reproduce the error. But I think the problem might be that you define the columns of your CTE here:
Profit_Score_CTE( [Emp or Vendor ID], [Project Profit by Person %] ) AS (
And yet you alias your second column with a different name here:
AS [Profit Score]
You need to decide which column name you want your CTE to expose and use it consistently.
I'll assume your CTE is correctly defined. Your cte is named "Profit_Score_CTE". Your actual select statement refers to objects dbo.PS_Emp and dbo.PS. I'll guess that you should replace dbo.PS with your CTE name. E.g.,
with Profit_Score_CTE as (select ...)
select emp.[Employee Name], ...
from dbo.PS_Emp as emp
left join Profit_Score_CTE
on emp.USID = Profit_Score_CTE.[Emp or Vendor ID]
order by ...
;
The alias PS is visible only inside the definition of the CTE. It cannot be used in the actual select statement that uses your CTE. Notice that I gave your table an alias and used it - a consistent coding style is something you should strive to achieve. Also notice the order by clause. Rows within a resultset have no defined order without one - and usually it is important. And PLEASE use white space to make your code readable and to avoid easy mistakes. You crammed everything together in the formula for computed column [Final Score].
Thanks all for your help!
My newbie ribbon was really showing with this one. The problem had nothing to do with SQL at all. I wasn't pointing to the correct database in sql server.
In the available databases drop down box on the top left hand screen of SQL Server you need to select the database you're working from. This will enable the script to find your database, and begin to solve alot of the errors.

Dynamically measured measure (MDX)

good night!
I'm new to the MDX world and I'm having a hard time creating a calculated measure, the problem is this: I have a measure that is calculated using the final balance of the previous month as the balance of the current month. Something similar to what they see below.
This is how the data should appear
The problem is that the mdx script I did not add the previous data to the display and so it ends up showing me an incorrect initial value. In the image above it should return the final balance calculated from the beginning of the company to the selected filter. Can anyone help me?
This is how it is showing up.
Here is the mdx query I created:
with Member [Saldo Final 2] as
([Measures].[Certificados Novos] + [Measures].[Reativados] - [Measures].[Cancelados Menor ou Igual a 6 Parcela] - [Measures].[Cancelados Maior que a 6 Parcela])
member [Saldo Final Mês Anterior 2] as
(ParallelPeriod ([DIM TEMPO].[MES ANO].[MES ANO]
, 1
, [DIM TEMPO].[MES ANO].CurrentMember
), [Saldo Final 2])
member [Saldo Inicial 2] as
Sum([DIM TEMPO].[MES ANO].CurrentMember.FirstSibling:[DIM TEMPO].[MES ANO].CurrentMember, [Saldo Final Mês Anterior 2])
member [Final] as
[Saldo Inicial] + [Measures].[Saldo Final 2]
select [DIM TEMPO].[MES ANO].[MES ANO] on columns,
{[Measures].[Certificados Novos], [Measures].[Reativados], [Measures].[Cancelados Menor ou Igual a 6 Parcela],
[Measures].[Cancelados Maior que a 6 Parcela], [Final]
} on rows
from [dw_sinaf]
where
{[DIM TEMPO].[ANO].&[2016]}
Not sure it's exactly what are you looking for, but I was able to do it on a simplified model:
Two measures are available:
Sales Only Units
Return Only Units
We need to have a SUM for every Day (Month in your example) running month-by-month from the initial Date.
Code for FINAL and INICIAL is here:
with member [Final] as
([Date].[Year Qtr Month].[Date].&[20170501]
,[Measures].[Sales Only Units])
+
SUM([Date].[Year Qtr Month].[Date].&[20170501]
:[Date].[Year Qtr Month].CurrentMember
,[Measures].[Return Only Units])
member [Inicial] as
([Final]-[Measures].[Return Only Units])
select non empty [Date].[YQM].[Date].members on 0
,{[Inicial],[Measures].[Sales Only Units],[Measures].[Return Only Units],[Final]} on 1
from [My_Cube]
BLUE is initial value "from the beginning of the company"
RED values to use if required to use another initial date
GREEN required running value
[Sales Only Units] should be ideally hidden for every member, except initial date in order not to confuse business users.

How to filter on mdx dimension

I have a query which i want to filter it on max of one of its dimension fields like this:
SELECT
{
[Measures].[F Sra Quantity],
[Measures].[F Sra Gross],
[Measures].[F Sra Disc TOTAL]
}
DIMENSION PROPERTIES PARENT_UNIQUE_NAME,HIERARCHY_UNIQUE_NAME
ON COLUMNS,
NON EMPTY
CrossJoin(
{[Branch Dim].[b Name].Children},
{[Date Dim].[d Year Month].Children},
{[Date Dim].[Full Date].Children},
{[Customer Dim].[c Name].Children},
{[Customer Dim].[c Path].Children},
{[Order Specification Dim].[Os Type No].Children},
{[Sales Team Dim].[Id].Children},
{[Sales Team Dim].[St Visitor].Children}
)
ON ROWS
FROM [D Sys Warehouse]
I want to filter it on the max value of [Os Type No] which its members are changing always. would you help me please?
Not tested as I'm not near SSAS or the AdvWrks cube but something along these lines might work, assuming I have interpreted your request correctly:
WITH MEMBER [Measures].[MAX_No] AS
MAX(
[Order Specification Dim].[Os Type No].MEMBERS,
[Order Specification Dim].[Os Type No].CURRENTMEMBER.MEMBER_VALUE
)
SELECT
{
[Measures].[F Sra Quantity],
[Measures].[F Sra Gross],
[Measures].[F Sra Disc TOTAL]
}
DIMENSION PROPERTIES PARENT_UNIQUE_NAME,HIERARCHY_UNIQUE_NAME
ON COLUMNS,
NON EMPTY
CrossJoin(
{[Branch Dim].[b Name].Children},
{[Date Dim].[d Year Month].Children},
{[Date Dim].[Full Date].Children},
{[Customer Dim].[c Name].Children},
{[Customer Dim].[c Path].Children},
{[Order Specification Dim].[Os Type No].Children},
{[Sales Team Dim].[Id].Children},
{[Sales Team Dim].[St Visitor].Children}
)
HAVING
[Order Specification Dim].[Os Type No].CURRENTMEMBER.MEMBER_VALUE = [Measures].[MAX_No]
ON ROWS
FROM [D Sys Warehouse]

How to store the results of a select statement and be able to use it again in another select statement PL\SQL Oracle

I am trying to store the result of a select statement (in temp memory maybe?) and then call the saved result and be able to use it again in other selects so it doesn't have to execute again and again which would increase the execution time. I was thinking maybe using a procedure or a cursor would be the solution, but I'm know enough SQL to be able to use it, any help would be helpful!
Here is the select statement that I would like to store:
select "PO Number2", "Total"
from (select distinct "PO Number2", sum("Amount") as "Total"
from (select distinct account as Account,
company as Company,
year_period_key as "Year Period Key",
voucher_no as "Voucher No",
voucher_type as "Vou Type",
voucher_date as "GRN/Invoice Date",
reference_number as "PO Number2",
code_c as "Project ID",
ifsapp.PURCHASE_ORDER_API.Get_Vendor_No(reference_number) as "Supplier ID",
ifsapp.SUPPLIER_INFO_API.Get_Name(ifsapp.PURCHASE_ORDER_API.Get_Vendor_No(reference_number)) as "Supplier Name",
sum(quantity) as "Quantity",
sum(amount) as "Amount",
sum(debet_amount) as "Debit Amount",
sum(credit_amount) as "Credit Amount"
from ifsapp.GEN_LED_VOUCHER_ROW_UNION_QRY
where account = '222010'
and Voucher_Type = '0'
group by voucher_type,
account,
year_period_key,
voucher_date,
reference_number,
code_c,
company,
voucher_no,
party_type_id
union all
select distinct account as Account,
company as Company,
year_period_key as "Year Period Key",
voucher_no as "Voucher No",
voucher_type as "Vou Type",
voucher_date as "GRN/Invoice Date",
ifsapp.MAN_SUPP_INVOICE_API.Get_Purchase_Order_Ref_Number(company,
party_type_id,
'Supplier',
reference_number) as "PO Number2",
code_c as "Project ID",
ifsapp.PURCHASE_ORDER_API.Get_Vendor_No(ifsapp.MAN_SUPP_INVOICE_API.Get_Purchase_Order_Ref_Number(company,
party_type_id,
'Supplier',
reference_number)) as "Supplier ID",
ifsapp.SUPPLIER_INFO_API.Get_Name(ifsapp.PURCHASE_ORDER_API.Get_Vendor_No(ifsapp.MAN_SUPP_INVOICE_API.Get_Purchase_Order_Ref_Number(company,
party_type_id,
'Supplier',
reference_number))) as "Supplier Name",
sum(quantity) as "Quantity",
sum(amount) as "Amount",
sum(debet_amount) as "Debit Amount",
sum(credit_amount) as "Credit Amount"
from ifsapp.GEN_LED_VOUCHER_ROW_UNION_QRY
where account = '222010'
and Voucher_Type = 'J'
group by voucher_type,
account,
year_period_key,
voucher_date,
reference_number,
code_c,
company,
voucher_no,
party_type_id)
where "Year Period Key" <= '&YearPeriodKey'
group by "PO Number2")
where "Total" = 0
Thanks In advance! :)
Oracle has it's own optimizers that help you not perform the same query multiple times. It'll store the results on the server memory (limited) if the query is exactly the same. So if you perform this query 5 times in one minute, it'll will not consume many resources. In advance, you should see if a materialized view does not solve you problem.
Are you wanting to "store" the result and re-use within a single session or to store the result for other sessions to re-use. To materialize teh query data such that it becomes visible to other sessions, and remains so until such time as a refresh is invoke (manually or scehudled), then really you're looking at materialised views. If this is just for the purpose of a single session/job and prevent having to re-query the data repeatedly, remember that with ref-cursors you can only go forwards. You could write the data to a PLSQL table (array/collection), but if the dataset is large, watch out for memory. For larger datasets, probably the best bet are temporary tables.