我需要一个DAX公式来计算连续年数。

huangapple go评论71阅读模式
英文:

I need a DAX formula to calculate number of consecutive year

问题

我正在尝试获取DAX公式,以获取客户与我们合作的连续年数。同一客户(注册号)可能在同一年内有多次记录。如果年份之间存在间隙,则计数将重置。附有示例数据和预期结果。

我已经根据此资源修改了公式:https://community.fabric.microsoft.com/t5/Desktop/Calculating-Consecutive-Years-Active/td-p/1670339,但公式的结果不是我预期的:

连续年数 = 
VAR vMaxYear =
    MAX ( 'Data: Policy'[Effective year] )
VAR vThisCustomer =
    MIN ( 'Data: Policy'[Transformed Register number])
VAR vLatestNotDonation =
    MAXX (
        FILTER (
            ALL ( 'Data: Policy'[Effective year]),
            ISBLANK (
                CALCULATE (
                    COUNTROWS ( 'Data: Policy' ),
                    'Data: Policy'[Transformed Register number] = vThisCustomer
                )
            )
        ),
        'Data: Policy'[Effective year]
    )
VAR vLatestIfBlank =
    IF (
        ISBLANK ( vLatestNotDonation ),
        MINX (
            ALL ( 'Data: Policy'[Effective year] ),
            'Data: Policy'[Effective year]
        ) - 1,
        vLatestNotDonation
    )
RETURN
    IF (
        vMaxYear = 2023,
        vMaxYear - vLatestIfBlank
    )

|Effective year |Register number |Formula Outcome |Expected ConsecutiveYears|
|:---- |:-----:|----:|
|2017 |AX1234 |0 |1|
|2018 |AX1234 |0 |2|
|2020 |AX1234 |0 |1|
|2020 |AX1234 |0 |1|
|2021 |AX1234 |0 |2|
|2022 |AX1234 |1 |3|
|2023 |AX1234 |1 |4|
|2023 |AX1234 |1 |4|
|2023 |AX1234 |1 |4|
|2023 |AX1234 |1 |4|
|2023 |AX1234 |1 |4|

感谢您的帮助。非常感谢。

英文:

I am trying to get code DAX formula to get number of consective year a client is with us. There may be multiple entry in a year for the same client (Register number). Then count shall reset if there is a gap between the years. Sample data and expected outcome is attached

我需要一个DAX公式来计算连续年数。

I have modified the formula from this resource: https://community.fabric.microsoft.com/t5/Desktop/Calculating-Consecutive-Years-Active/td-p/1670339 but the Formula result is not what i expected:

Consecutive Yrs = 
VAR vMaxYear =
    MAX ( 'Data: Policy'[Effective year] )
VAR vThisCustomer =
    MIN ( 'Data: Policy'[Transformed Register number])
VAR vLatestNotDonation =
    MAXX (
        FILTER (
            ALL ( 'Data: Policy'[Effective year]),
            ISBLANK (
                CALCULATE (
                    COUNTROWS ( 'Data: Policy' ),
                    'Data: Policy'[Transformed Register number] = vThisCustomer
                )
            )
        ),
        'Data: Policy'[Effective year]
    )
VAR vLatestIfBlank =
    IF (
        ISBLANK ( vLatestNotDonation ),
        MINX (
            ALL ( 'Data: Policy'[Effective year] ),
            'Data: Policy'[Effective year]
        ) - 1,
        vLatestNotDonation
    )
RETURN
    IF (
        vMaxYear = 2023,
        vMaxYear - vLatestIfBlank
    )

|Effective year |Register number |Formula Outcome |Expected ConsecutiveYears|
|:---- |:-----:|----:|
|2017 |AX1234 |0 |1|
|2018 |AX1234 |0 |2|
|2020 |AX1234 |0 |1|
|2020 |AX1234 |0 |1|
|2021 |AX1234 |0 |2|
|2022 |AX1234 |1 |3|
|2023 |AX1234 |1 |4|
|2023 |AX1234 |1 |4|
|2023 |AX1234 |1 |4|
|2023 |AX1234 |1 |4|
|2023 |AX1234 |1 |4|

Appreciate your assistance. Many thanks

答案1

得分: 2

I think I found a better way without applying so many transformations and that's why I have labeled my earlier solution as Solution-2 and labeled the new solution as Solution-1.

Solution-1

First create a Measure as below-

check_break_measure = 

var cr_year = min(your_table_name[Effective year])
var cr_reg_number = MIN(your_table_name[Transformed Register number])

var prev_year = CALCULATE(
    max(your_table_name[Effective year]),
    FILTER(
        all(your_table_name),
        your_table_name[Effective year] < cr_year
            && your_table_name[Transformed Register number] = cr_reg_number
    )
)

return if(ISBLANK(prev_year) || cr_year - prev_year >= 2, 1,0)

And then the second Measure as below-

serial_no = 

var current_row_year = min(your_table_name[Effective year])
var current_row_reg_number = min(your_table_name[Transformed Register number])

var break_year_current_group = 
CALCULATE(
    max(your_table_name[Effective year]),
    FILTER(
        all(your_table_name),
        your_table_name[Effective year] <= current_row_year
            && your_table_name[check_break_measure] = 1
            && your_table_name[Transformed Register number] == current_row_reg_number
    )
)

var sl = 
CALCULATE(
    DISTINCTCOUNT(your_table_name[Effective year]),
    FILTER(
        all(your_table_name),
        your_table_name[Effective year] <= current_row_year
            && your_table_name[Effective year] >= break_year_current_group
            && your_table_name[Transformed Register number] == current_row_reg_number
    )
)

Return sl

Both above and below solution you will get the same output


Solution-2

If you can do some transformation in your table in the power query editor and then create a Measure, you can achieve the requirement.

First, apply these below code to your table's Advance Editor-

let
    //Existing Steps,
    

    //new steps started from here
    //please edit "your_previous_step_name" properly in the below line with your actual your_previous_step_name

    #"Sorted Rows1" = Table.Sort(#"your_previous_step_name",{{"Transformed Register number", Order.Ascending}, {"Effective year", Order.Ascending}}),
    #"Added Index" = Table.AddIndexColumn(#"Sorted Rows1", "Index", 1, 1, Int64.Type),
    #"Reordered Columns" = Table.ReorderColumns(#"Added Index",{"Index", "Effective year"}),
    #"Added Custom" = Table.AddColumn(#"Reordered Columns", "Index_", each [Index]+1),
    #"Reordered Columns1" = Table.ReorderColumns(#"Added Custom",{"Index", "Index_", "Transformed Register number", "Effective year"}),
    #"Merged Queries" = Table.NestedJoin(#"Reordered Columns1", {"Index"}, #"Reordered Columns1", {"Index_"}, "Reordered Columns1", JoinKind.LeftOuter),
    #"Expanded Reordered Columns1" = Table.ExpandTableColumn(#"Merged Queries", "Reordered Columns1", {"Transformed Register number", "Effective year"}, {"Reordered Columns1.Cat", "Reordered Columns1.Year"}),
    #"Renamed Columns" = Table.RenameColumns(#"Expanded Reordered Columns1",{{"Reordered Columns1.Cat", "pr_cat"}, {"Reordered Columns1.Year", "pr_year"}}),
    #"Sorted Rows" = Table.Sort(#"Renamed Columns",{{"Index", Order.Ascending}}),
    #"Added Custom1" = Table.AddColumn(#"Sorted Rows", "check_break", each if [Transformed Register number] <> [pr_cat] or [Effective year] - [pr_year] >=2 then 1 else 0),
    #"Removed Columns" = Table.RemoveColumns(#"Added Custom1",{"Index_", "pr_cat", "pr_year"})
in
    #"Removed Columns"

Considering your sample data, you will have data as below now-

我需要一个DAX公式来计算连续年数。

Now go to the Report designer and create a new Measure with this below code-

serial_no = 

var current_row_year = min(your_table_name[Effective year])
var current_row_reg_number = min(your_table_name[Transformed Register number])

var break_year_current_group = 
CALCULATE(
    max(your_table_name[Effective year]),
    FILTER(
        all(your_table_name),
        your_table_name[Effective year] <= current_row_year
            && your_table_name[check_break] = "1"
            && your_table_name[Transformed Register number] == current_row_reg_number
    )
)

var sl = 
CALCULATE(
    DISTINCTCOUNT(your_table_name[Effective year]),
    FILTER(
        all(your_table_name),
        your_table_name[Effective year] <= current_row_year
            && your_table_name[Effective year] >= break_year_current_group
            && your_table_name[Transformed Register number] == current_row_reg_number
    )
)

Return sl

Your final data output will be as below-

我需要一个DAX公式来计算连续年数。


I hope this helps!

<details>
<summary>英文:</summary>

I think I found a better way without applying so many transformations and that&#39;s why I have labeled my earlier solution as **Solution-2** and labeled the new solution as **Solution-1**.


**Solution-1**

First create a **Measure** as below-

check_break_measure =

var cr_year = min(your_table_name[Effective year])
var cr_reg_number = MIN(your_table_name[Transformed Register number])

var prev_year = CALCULATE(
max(your_table_name[Effective year]),
FILTER(
all(your_table_name),
your_table_name[Effective year] < cr_year
&& your_table_name[Transformed Register number] = cr_reg_number
)
)

return if(ISBLANK(prev_year) || cr_year - prev_year >= 2, 1,0)


And then the second **Measure** as below-

serial_no =

var current_row_year = min(your_table_name[Effective year])
var current_row_reg_number = min(your_table_name[Transformed Register number])

var break_year_current_group =
CALCULATE(
max(your_table_name[Effective year]),
FILTER(
all(your_table_name),
your_table_name[Effective year] <= current_row_year
&& your_table_name[check_break_measure] = 1
&& your_table_name[Transformed Register number] == current_row_reg_number
)
)

var sl =
CALCULATE(
DISTINCTCOUNT(your_table_name[Effective year]),
FILTER(
all(your_table_name),
your_table_name[Effective year] <= current_row_year
&& your_table_name[Effective year] >= break_year_current_group
&& your_table_name[Transformed Register number] == current_row_reg_number
)
)

Return sl


**Both above and below solution you will get the same output**

-----
**Solution-2**

If you can do some transformation in your table in the power query editor and then create a Measure, you can achieve the requirement.

First, apply these below code to your table&#39;s **Advance Editor**-

let
//Existing Steps,

//new steps started from here
//please edit &quot;your_previous_step_name&quot; properly in the below line with your actual your_previous_step_name

#&quot;Sorted Rows1&quot; = Table.Sort(#&quot;your_previous_step_name&quot;,{{&quot;Transformed Register number&quot;, Order.Ascending}, {&quot;Effective year&quot;, Order.Ascending}}),
#&quot;Added Index&quot; = Table.AddIndexColumn(#&quot;Sorted Rows1&quot;, &quot;Index&quot;, 1, 1, Int64.Type),
#&quot;Reordered Columns&quot; = Table.ReorderColumns(#&quot;Added Index&quot;,{&quot;Index&quot;, &quot;Effective year&quot;}),
#&quot;Added Custom&quot; = Table.AddColumn(#&quot;Reordered Columns&quot;, &quot;Index_&quot;, each [Index]+1),
#&quot;Reordered Columns1&quot; = Table.ReorderColumns(#&quot;Added Custom&quot;,{&quot;Index&quot;, &quot;Index_&quot;, &quot;Transformed Register number&quot;, &quot;Effective year&quot;}),
#&quot;Merged Queries&quot; = Table.NestedJoin(#&quot;Reordered Columns1&quot;, {&quot;Index&quot;}, #&quot;Reordered Columns1&quot;, {&quot;Index_&quot;}, &quot;Reordered Columns1&quot;, JoinKind.LeftOuter),
#&quot;Expanded Reordered Columns1&quot; = Table.ExpandTableColumn(#&quot;Merged Queries&quot;, &quot;Reordered Columns1&quot;, {&quot;Transformed Register number&quot;, &quot;Effective year&quot;}, {&quot;Reordered Columns1.Cat&quot;, &quot;Reordered Columns1.Year&quot;}),
#&quot;Renamed Columns&quot; = Table.RenameColumns(#&quot;Expanded Reordered Columns1&quot;,{{&quot;Reordered Columns1.Cat&quot;, &quot;pr_cat&quot;}, {&quot;Reordered Columns1.Year&quot;, &quot;pr_year&quot;}}),
#&quot;Sorted Rows&quot; = Table.Sort(#&quot;Renamed Columns&quot;,{{&quot;Index&quot;, Order.Ascending}}),
#&quot;Added Custom1&quot; = Table.AddColumn(#&quot;Sorted Rows&quot;, &quot;check_break&quot;, each if [Transformed Register number] &lt;&gt; [pr_cat] or [Effective year] - [pr_year] &gt;=2 then 1 else 0),
#&quot;Removed Columns&quot; = Table.RemoveColumns(#&quot;Added Custom1&quot;,{&quot;Index_&quot;, &quot;pr_cat&quot;, &quot;pr_year&quot;})

in
#"Removed Columns"


Considering your sample data, you will have data as below now-

[![enter image description here][1]][1]

Now go to the Report designer and create a new **Measure** with this below code-

serial_no =

var current_row_year = min(your_table_name[Effective year])
var current_row_reg_number = min(your_table_name[Transformed Register number])

var break_year_current_group =
CALCULATE(
max(your_table_name[Effective year]),
FILTER(
all(your_table_name),
your_table_name[Effective year] <= current_row_year
&& your_table_name[check_break] = "1"
&& your_table_name[Transformed Register number] == current_row_reg_number
)
)

var sl =
CALCULATE(
DISTINCTCOUNT(your_table_name[Effective year]),
FILTER(
all(your_table_name),
your_table_name[Effective year] <= current_row_year
&& your_table_name[Effective year] >= break_year_current_group
&& your_table_name[Transformed Register number] == current_row_reg_number
)
)

Return sl


Your final data output will be as below-

[![enter image description here][2]][2]


  [1]: https://i.stack.imgur.com/UCP5o.png
  [2]: https://i.stack.imgur.com/fPzQp.png

</details>



huangapple
  • 本文由 发表于 2023年6月6日 17:15:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76413125.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定