I want to create a measure for the running total of sales.
The customer dimension need to be ordered by their sales amount.
Want I want to get:
H1
Sales
CumSales
B
10
10
C
3
13
A
2
15
Thank you!
If I use
CREATE MEMBER CURRENTCUBE.[Measures].[CumSales]
AS sum({null: [Kunden].[H1].CurrentMember}, [Measures].[ABSTCK In Mille]),
FORMAT_STRING = "Numeric",
NON_EMPTY_BEHAVIOR = { [ABSTCK In Mille] },
VISIBLE = 1 , DISPLAY_FOLDER = 'Calculations' , ASSOCIATED_MEASURE_GROUP = 'SAP Sales';
(H1 is the customer hierachy name and represents the customer)
I get:
H1
Sales
CumSales
A
2
2
B
10
12
C
3
15
What I also managed (and might be used?) is to create the ordered customer Set ("KundenOrderedByABSTCK") and create a measure for the order index ("KundenOrderedByABSTCK_RowNr")
CREATE DYNAMIC SET CURRENTCUBE.[KundenOrderedByABSTCK]
AS order([Kunden].[H1].[H1].Members,[Measures].[ABSTCK In Mille],DESC) ;
//works fine
//Ranking Nr.
CREATE MEMBER CURRENTCUBE.[Measures].[KundenOrderedByABSTCK_RowNr]
AS RANK([Kunden].[H1].CurrentMember, KundenOrderedByABSTCK),
FORMAT_STRING = "0",
NON_EMPTY_BEHAVIOR = { [ABSTCK In Mille] },
VISIBLE = 1 , DISPLAY_FOLDER = 'Calculations' , ASSOCIATED_MEASURE_GROUP = 'SAP Sales';
Related
Hello being facing an issue with the following :
I need to select a list of product based on max budget,
Data
Item 1 : 1 usd
Item 2 : 3 usd
Item 3 : 0.5 usd
Item 4 : 40 usd
Item 5 : 20 usd
Item 6 : 5 usd
Budget = 50 usd
The needed output : different list of product i can get where the sum of price is equal to or less than 50 usd,list can contain 1 products as well.
Any help will be much appreciated.
Language : Vba or M query
In powerquery: Create every combination. Price them. Filter amount as needed
function Combinations
(Items as list) as table =>
// Bill Szysz 2017, all combinations of items in list, blows up with too many items to process due to large number of combinations
let AddIndex = Table.AddIndexColumn(Table.FromList(Items), "Index", 0, 1),
ReverseIndeks = Table.AddIndexColumn(AddIndex, "RevIdx", Table.RowCount(AddIndex), -1),
Lists = Table.AddColumn(ReverseIndeks, "lists", each
List.Repeat(
List.Combine({
List.Repeat({[Column1]}, Number.Power(2,[RevIdx]-1)),
List.Repeat( {null}, Number.Power(2,[RevIdx]-1))
})
, Number.Power(2, [Index]))
),
ResultTable = Table.FromColumns(Lists[lists])
in ResultTable
used with code:
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Item", type text}, {"Amount", type number}}),
GetCombos = Combinations(#"Changed Type"[Item]),
#"Added Index" = Table.AddIndexColumn(GetCombos, "Index", 0, 1, Int64.Type),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Added Index", {"Index"}, "Attribute", "Value"),
#"Merged Queries" = Table.NestedJoin(#"Unpivoted Other Columns", {"Value"}, #"Changed Type", {"Item"}, "ct", JoinKind.LeftOuter),
#"Expanded ct" = Table.ExpandTableColumn(#"Merged Queries", "ct", {"Amount"}, {"Amount"}),
#"Group"= Table.Group(#"Expanded ct", {"Index"}, {
{"Concat", each Text.Combine([Value],", "), type text},
{"Cost", each List.Sum([Amount]), type number}}
),
#"Removed Columns" = Table.RemoveColumns(Group,{"Index"}),
#"Filtered Rows" = Table.SelectRows(#"Removed Columns", each [Cost] <= 50)
in #"Filtered Rows"
Given data as such:
Month ValueA
1 T
2 T
3 T
4 F
Is there a way to make a measure that would find if for each month, last three Values were True?
So the output would be (F,F,T,F)?
That would propably mean that my actual problem is solvable, which is finding from:
Month ValueA ValueB ValueC
1 T F T
2 T T T
3 T T T
4 F T F
the count of those booleans for each row, so the output would be (0,0,2[A and C],1[B])
EDIT:
Okay, I managed to solve the first part with this:
Previous =
VAR PreviousDate =
MAXX(
FILTER(
ALL( 'Table' ),
EARLIER( 'Table'[Month] ) > 'Table'[Month]
),
'Table'[Month]
)
VAR PreviousDate2 =
MAXX(
FILTER(
ALL( 'Table' ),
EARLIER( 'Table'[Month] ) - 1 > 'Table'[Month]
),
'Table'[Month]
)
RETURN
IF(
CALCULATE(
MAX( 'Table'[Value] ),
FILTER(
'Table',
'Table'[Month] = PreviousDate
)
) = "T"
&& CALCULATE(
MAX( 'Table'[Value] ),
FILTER(
'Table',
'Table'[Month] = PreviousDate2
)
) = "T"
&& 'Table'[Value] = "T",
TRUE,
FALSE
)
But is there a way to use it with unknown number of columns?
Without hard - coding every column name? Like a loop or something.
I would redo the data table in power query (upivoting the ValueX-columns) and changing T/F to 1/0. Then have a dim table with a relationship to Month, like this:
Then add a measure like this:
Three Consec T =
var maxMonth = MAX('Data'[Month])
var tempTab =
FILTER(
dimMonth;
'dimMonth'[MonthNumber] <= maxMonth && 'dimMonth'[MonthNumber] > maxMonth -3
)
var sumMonth =
MAXX(
'dimMonth';
CALCULATE(
SUM('Data'[OneOrZero]);
tempTab
)
)
return
IF(
sumMonth >= 3;
"3 months in a row";
"No"
)
Then I can have a visual like this when the slicer indicates which time window I'm looking at and the table shows if there has been 3 consecutive Ts or not.
Let's say I have a .CSV which has three columns: tidytext, location, vader_senti
I was already able to get the amount of *positive, neutral and negative text instead of word* pero country using the following code:
data_vis = pd.read_csv(r"csviamcrpreprocessed.csv", usecols=fields)
def print_sentiment_scores(text):
vadersenti = analyser.polarity_scores(str(text))
return pd.Series([vadersenti['pos'], vadersenti['neg'], vadersenti['neu'], vadersenti['compound']])
data_vis[['vadersenti_pos', 'vadersenti_neg', 'vadersenti_neu', 'vadersenti_compound']] = data_vis['tidytext'].apply(print_sentiment_scores)
data_vis['vader_senti'] = 'neutral'
data_vis.loc[data_vis['vadersenti_compound'] > 0.3 , 'vader_senti'] = 'positive'
data_vis.loc[data_vis['vadersenti_compound'] < 0.23 , 'vader_senti'] = 'negative'
data_vis['vader_possentiment'] = 0
data_vis.loc[data_vis['vadersenti_compound'] > 0.3 , 'vader_possentiment'] = 1
data_vis['vader_negsentiment'] = 0
data_vis.loc[data_vis['vadersenti_compound'] <0.23 , 'vader_negsentiment'] = 1
data_vis['vader_neusentiment'] = 0
data_vis.loc[(data_vis['vadersenti_compound'] <=0.3) & (data_vis['vadersenti_compound'] >=0.23) , 'vader_neusentiment'] = 1
sentimentbylocation = data_vis.groupby(["Location"])['vader_senti'].value_counts()
sentimentbylocation
sentimentbylocation gives me the following results:
Location vader_senti
Afghanistan negative 151
positive 25
neutral 2
Albania negative 6
positive 1
Algeria negative 116
positive 13
neutral 4
TO GET THE MOST COMMON POSITIVE WORDS, I USED THIS CODE:
def process_text(text):
tokens = []
for line in text:
toks = tokenizer.tokenize(line)
toks = [t.lower() for t in toks if t.lower() not in stopwords_list]
tokens.extend(toks)
return tokens
tokenizer=TweetTokenizer()
punct = list(string.punctuation)
stopwords_list = stopwords.words('english') + punct + ['rt','via','...','…','’','—','—:',"‚","â"]
pos_lines = list(data_vis[data_vis.vader_senti == 'positive'].tidytext)
pos_tokens = process_text(pos_lines)
pos_freq = nltk.FreqDist(pos_tokens)
pos_freq.most_common()
Running this will give me the most common words and the number of times they appeared, such as
[(good, 1212),
(amazing, 123)
However, what I want to see is how many of these positive words appeared in a country.
For example:
I have a sample CSV here: https://drive.google.com/file/d/112k-6VLB3UyljFFUbeo7KhulcrMedR-l/view?usp=sharing
Create a column for each most_common word, then do a groupby location and use agg to apply a sum for each count:
words = [i[0] for i in pos_freq.most_common()]
# lowering all cases in tidytext
data_vis.tidytext = data_vis.tidytext.str.lower()
for i in words:
data_vis[i] = data_vis.tidytext.str.count(i)
funs = {i: 'sum' for i in words}
grouped = data_vis.groupby('Location').agg(funs)
Based on the example from the CSV and using most_common as ['good', 'amazing'] the result would be:
grouped
# good amazing
# Location
# Australia 0 1
# Belgium 6 4
# Japan 2 1
# Thailand 2 0
# United States 1 0
SELECT * FROM Fruit
INNER JOIN Apple ON Fruit.Id = Apple.FruitId
WHERE Apple.Type = 1 AND Apple.Type = 3
I need to get unique rows of Fruit that have both Apples that are of type 1 AND 3. Apple.Type is considered unique, but I wouldn't think it matters though.
With these rows, this should return two rows with both Fruit #50 and #52. The most important part is the Fruit.Id, I don't need to return the Types, but just need to make sure every single Fruit returned has at least one Apple.Type = 1 and one Apple.Type = 3.
Apple { Id = 1, FruitId = 50, Type = 0 }
Apple { Id = 2, FruitId = 50, Type = 1 }
Apple { Id = 3, FruitId = 50, Type = 3 }
Apple { Id = 4, FruitId = 51, Type = 1 }
Apple { Id = 5, FruitId = 51, Type = 2 }
Apple { Id = 6, FruitId = 52, Type = 3 }
Apple { Id = 7, FruitId = 52, Type = 1 }
Apple { Id = 8, FruitId = 52, Type = 2 }
Fruit { Id = 50 }
Fruit { Id = 51 }
Fruit { Id = 52 }
I'm not quite sure how to use DISTINCT and/or GROUP BY in order to form this query.
Group your apples table by fruit id and pick the results that have both desired types. Use this to get your fruits.
SELECT *
FROM Fruit
WHERE id IN
(
SELECT FruitId
FROM Apple
WHERE Type IN (1,3)
GROUP BY FruitId
HAVING COUNT(DISTINCT Type) = 2
);
This would return the fruits with ID 50 and 52.
SELECT *
FROM Fruit
WHERE EXISTS (
SELECT 1 FROM Apple
WHERE Type = 1 AND Apple.FruitId = Fruit.Id
) AND EXISTS (
SELECT 1 FROM Apple
WHERE Type = 3 AND Apple.FruitId = Fruit.Id
)
Not the most efficient way, but transposing those columns out so you have multiple types per fruitid should do it.
create table type_1 as select FruitId, Type as Type1 from Apple where Type = 1;
create table type_3 as select FruitId, Type as Type3 from Apple where Type = 3;
create table Fruits as select distinct FruitId from Apple;
create table Fruit_Agg as select a.FruitId, b.Type1, c.Type3 from Fruits a left join type_1 b on a.FruitId = b.FruitId left join type_3 c on a.FruitId = c.FruitId;
create table Types_1and_3 as select FruitId from Fruit_Agg where Type1 = 1 and Type3 = 3;
I have 3 calculated members defined in my SQL Server 2008 SSAS Cube..
CALCULATE;
/* Calculate Sales Volume */
CREATE MEMBER CURRENTCUBE.[Measures].[Ship Volume]
AS [Measures].[QTY SHIPPED] + [Measures].[QTY ADJUST],
FORMAT_STRING = "Standard",
NON_EMPTY_BEHAVIOR = { [QTY SHIPPED], [QTY ADJUST] },
VISIBLE = 1 , DISPLAY_FOLDER = 'Calculated Members' , ASSOCIATED_MEASURE_GROUP = 'Sales';
CREATE MEMBER CURRENTCUBE.[Measures].[Avg Price USD]
AS [Measures].[NET SALES] / [Measures].[SHIP VOLUME],
FORMAT_STRING = "Standard",
VISIBLE = 1 , DISPLAY_FOLDER = 'Calculated Members' , ASSOCIATED_MEASURE_GROUP = 'Sales' ;
CREATE MEMBER CURRENTCUBE.[Measures].[Avg Price CAD]
AS [Measures].[NET SALES CAD] / [Measures].[SHIP VOLUME],
FORMAT_STRING = "Standard",
VISIBLE = 1 , DISPLAY_FOLDER = 'Calculated Members' , ASSOCIATED_MEASURE_GROUP = 'Sales' ;
The syntax works fine, however when I look at my cube through Excel some of the values have #NUM! as the value.. not sure why this is? Is this because of divide by zero issue? How would I work around this?
Maybe check - A/B = C if B not equal 0 ? :
CALCULATE;
/* Calculate Sales Volume */
CREATE MEMBER CURRENTCUBE.[Measures].[Ship Volume]
AS [Measures].[QTY SHIPPED] + [Measures].[QTY ADJUST],
FORMAT_STRING = "Standard",
NON_EMPTY_BEHAVIOR = { [QTY SHIPPED], [QTY ADJUST] },
VISIBLE = 1 , DISPLAY_FOLDER = 'Calculated Members' , ASSOCIATED_MEASURE_GROUP = 'Sales';
CREATE MEMBER CURRENTCUBE.[Measures].[Avg Price USD]
AS Case
When IsEmpty([Measures].[SHIP VOLUME] )
THEN 0
ELSE [Measures].[NET SALES] / [Measures].[SHIP VOLUME] END,
FORMAT_STRING = "Standard",
VISIBLE = 1 , DISPLAY_FOLDER = 'Calculated Members' , ASSOCIATED_MEASURE_GROUP = 'Sales' ;
CREATE MEMBER CURRENTCUBE.[Measures].[Avg Price CAD]
AS Case
When IsEmpty([Measures].[SHIP VOLUME] )
THEN 0
ELSE [Measures].[NET SALES CAD] / [Measures].[SHIP VOLUME] END,
FORMAT_STRING = "Standard",
VISIBLE = 1 , DISPLAY_FOLDER = 'Calculated Members' , ASSOCIATED_MEASURE_GROUP = 'Sales' ;
Also you can try change IsEmpty([Measures].[SHIP VOLUME] )
to [Measures].[SHIP VOLUME]=0
EDIT
Try change this IsEmpty([Measures].[SHIP VOLUME] ) to
[Measures].[SHIP VOLUME] is null OR [Measures].[SHIP VOLUME]=0