我需要帮助统计客户之间的交叉点以及他们购买了哪些商品。例如,如果有5种产品,则客户可以购买任何一种产品或5种产品的任何组合。客户还可以在任何日期重新购买产品-这是我遇到的问题,因为最终用户希望能够查看任何选定日期范围的相交。
我设法提出了一个使用参数的解决方案,但这并不理想,因为最终用户无权更改报告的任何参数。
我愿意接受任何不涉及参数的解决方案,理想情况下,带有日期的切片器将是最佳解决方案
我在表上的字段是customer_ID,date_ID和产品
示例数据
customer_id date_id product
1 9/11/2018 A
1 10/11/2018 A
1 10/11/2018 B
1 11/11/2018 C
1 11/11/2018 A
2 9/11/2018 C
2 10/11/2018 D
2 11/11/2018 E
2 11/11/2018 A
3 10/11/2018 A
3 10/11/2018 B
3 11/11/2018 A
3 11/11/2018 B
3 11/11/2018 B
4 10/11/2018 A
4 11/11/2018 A
5 9/11/2018 A
5 10/11/2018 B
5 10/11/2018 E
5 10/11/2018 D
5 11/11/2018 C
5 11/11/2018 A
6 9/11/2018 A
6 10/11/2018 A
6 11/11/2018 A
具有不同切片器选择的可能输出
任何帮助都将不胜感激
答案 0 :(得分:0)
这很棘手,因为我想不出一种方法来将动态计算的表的值用作视觉中的字段。 (您可以创建计算表,但是这些表不对切片器做出响应。您还可以在度量内部创建动态计算表,但是度量不返回表,而仅返回单个值。)
我想到的唯一方法是为每种可能的产品组合创建一个表。但是,如果您有N个产品,则此表有2 N 行,并且会很快爆炸。
这是一个计算表,将输出所有组合:
Table2 =
VAR N = DISTINCTCOUNT(Table1[product])
VAR Products = SUMMARIZE(Table1,
Table1[product],
"Rank",
RANKX(ALL(Table1),
Table1[product],
MAX(Table1[product]),
ASC,
Dense
)
)
VAR Bits = SELECTCOLUMNS(GENERATESERIES(1, N), "Bit", [Value])
VAR BinaryString =
ADDCOLUMNS(
GENERATESERIES(1, 2^N),
"Binary",
CONCATENATEX(
Bits,
MOD( TRUNC( [Value] / POWER(2, [Bit]-1) ), 2)
,,[Bit]
,DESC
)
)
RETURN
ADDCOLUMNS(
BinaryString,
"Combination",
CONCATENATEX(Products, IF(MID([Binary],[Rank],1) = "1", [product], ""), "")
)
然后添加计算列以获取列分隔版本:
Delimited =
VAR Length = LEN(Table2[Combination])
RETURN
CONCATENATEX(
GENERATESERIES(1,Length),
MID(Table2[Combination], [Value], 1),
","
)
如果将Delimited
的“行”部分放在矩阵视觉上,并将以下度量放在“值”部分:
customers =
VAR Summary = SUMMARIZE(Table1,
Table1[customer_id],
"ProductList",
CONCATENATEX(VALUES(Table1[product]), Table1[product], ","))
RETURN SUMX(Summary, IF([ProductList] = MAX(Table2[Delimited]), 1, 0))
并过滤掉任何0个客户值,您应该得到类似这样的信息:
是的...不是一个很好的解决方案,特别是当N变大时,也许总比没有好?
编辑:
为了使用更长的产品名称,让我们在Combination
串联中使用定界符:
CONCATENATEX(Products, IF(MID([Binary],[Rank],1) = "1", [product], ""), ",")
(请注意,将""
更改为","
。)
然后重写Delimited
计算列以删除多余的逗号。
Delimited =
VAR RemoveMultipleCommas =
SUBSTITUTE(
SUBSTITUTE(
SUBSTITUTE(
SUBSTITUTE(Table2[Combination], ",,", ","),
",,", ","),
",,", ","),
",,", ",")
VAR LeftComma = (LEFT(Table2[Combination]) = ",")
VAR RightComma = (RIGHT(Table2[Combination]) = ",")
RETURN
IF(RemoveMultipleCommas <> ",",
MID(RemoveMultipleCommas,
1 + LeftComma,
LEN(RemoveMultipleCommas) - RightComma - LeftComma
), "")
最后,让我们对customers
进行一些修改,使其小计。
customers =
VAR Summary = SUMMARIZE(Table1,
Table1[customer_id],
"ProductList",
CONCATENATEX(VALUES(Table1[product]), Table1[product], ","))
VAR CustomerCount = SUMX(Summary, IF([ProductList] = MAX(Table2[Delimited]), 1, 0))
VAR Total = IF(ISFILTERED(Table2[Delimited]), CustomerCount, COUNTROWS(Summary))
RETURN IF(Total = 0, BLANK(), Total)
Total
变量给出了总计的客户总数。请注意,我还设置了零以返回为空白,这样您就不必过滤掉零(它将自动隐藏这些行)。
答案 1 :(得分:0)
You can also try this measure to calculate the result.
[Count Of Customers] :=
VAR var_products_selection_count = DISTINCTCOUNT ( Sales[product] )
VAR var_customers = VALUES ( Sales[customer_id] )
VAR var_customers_products_count =
ADDCOLUMNS(
var_customers,
"products_count",
VAR var_products_count =
COUNTROWS (
FILTER (
CALCULATETABLE ( VALUES ( Sales[product] ) ),
CONTAINS (
Sales,
Sales[product],
Sales[product]
)
)
)
RETURN var_products_count
)
RETURN
COUNTROWS (
FILTER (
var_customers_products_count,
[products_count] = var_products_selection_count
)
)
答案 2 :(得分:0)
我认为我找到了一个更好的解决方案/解决方法,它不需要预先计算所有可能的组合。关键是要使用排名/索引作为基础列,然后以此作为基础。
由于customer_id
已经很好地从1开始无索引的索引,在这种情况下,我将使用它,但是如果不是,那么您将要创建一个索引列来代替。请注意,由于每个客户只有一个组合,因此在给定的过滤器上下文中,没有比客户更多的独特产品组合。
对于每个索引/排名,我们要查找与其关联的产品组合以及该组合的客户数量。
ProductCombo =
VAR PerCustomer =
SUMMARIZE (
ALLSELECTED ( Table1 ),
Table1[customer_id],
"ProductList",
CONCATENATEX ( VALUES ( Table1[product] ), Table1[product], "," )
)
VAR ProductSummary =
SUMMARIZE (
PerCustomer,
[ProductList],
"Customers",
DISTINCTCOUNT ( Table1[customer_id] )
)
VAR Ranked =
ADDCOLUMNS (
ProductSummary,
"Rank",
RANKX (
ProductSummary,
[Customers] + (1 - 1 / RANKX ( ProductSummary, [ProductList] ) )
)
)
VAR CurrID =
SELECTEDVALUE ( Table1[customer_id] )
RETURN
MAXX ( FILTER ( Ranked, [Rank] = CurrID ), [ProductList] )
首先要做的是创建一个汇总表,以计算每个客户的产品列表。
然后,您使用该表并汇总不同的产品列表,并计算具有每种特定组合的客户数量。
然后,我在前一张表中添加一个排名列,该列首先按客户数量排序,并使用产品列表的字典顺序来平局决胜。
最后,我从该表中提取产品列表,其排名与当前行的索引/排名匹配。
您可以对客户数量进行几乎相同的度量,但这是我使用的度量,它稍微简单一些,可以处理0个值和总计:
Customers =
VAR PerCustomer =
SUMMARIZE (
ALLSELECTED ( Table1 ),
Table1[customer_id],
"ProductList",
CONCATENATEX ( VALUES ( Table1[product] ), Table1[product], "," )
)
VAR ProductCombo = [ProductCombo]
VAR CustomerCount =
SUMX ( PerCustomer, IF ( [ProductList] = ProductCombo, 1, 0 ) )
RETURN
IF (
ISFILTERED ( Table1[customer_id] ),
IF ( CustomerCount = 0, BLANK (), CustomerCount ),
DISTINCTCOUNT ( Table1[customer_id] )
)
结果看起来像这样