计算DAX中倒数第三的平均值

时间:2019-02-21 14:33:13

标签: dax ssas-tabular

我正在尝试获取工资按升序排序的数据的下三分之一的平均值。我试图使用FILTER返回TOPN,以不包括BLANK()工资值。然后,我只需要选择AVERAGE计算中我关心的列即可。因此,我写了类似以下内容的内容,其中[withSalaryJobCount]是一个计算得出的度量,它只是具有非空白的AnnualSalary列的行的计数:

entryWages:= AVERAGE(
        SELECTCOLUMNS(
            CALCULATE(
                TOPN(
                    [withSalaryJobCount]- [withSalaryJobCount]/3,
                    'table',
                    'table'[salaryAnnual],
                    ASC
                    ),
                FILTER(table, [salaryAnnual] <> BLANK())
            ),[entryWages]
            "bottomThird",
            [salaryAnnual]
        )
    )

失败,并显示以下错误:

The AVERAGE function only accepts a column reference as an argument

原始问题: 我有一组SQL计算,这些计算可以给我百分位数的工资以及我们所说的入门和经验水平的工资。工资列表输入到一个表中,该表按其值和IDENTITY列进行排序。下面列出了一个非常简化的查询,用于插入和计算百分位数,分录和有经验的工资:

CREATE TABLE #t1 (
    id int identity,
    salaryannual decimal(18,2)
    )
INSERT INTO #t1
SELECT salaryannual
FROM table a
ORDER BY salaryannual

SELECT  
    (SELECT AVG(CAST(salaryannual AS BIGINT)) FROM #t1 WHERE ID>=minID AND ID<=minID+(ct/3)) entryLevelSalary,  
    (SELECT AVG(CAST(salaryannual AS BIGINT)) FROM #t1 WHERE ID>=maxID-(ct/3) AND ID<=maxID) experiencedSalary,
    (select AVG(CAST(salaryannual AS BIGINT)) from #t1 where ID = minID + (ct/2+1)/2 or ID = minID + (ct/2+1)/2 + (ct/2+1)%2) q1, 
    (select AVG(CAST(salaryannual AS BIGINT)) from #t1 where ID = minID + (ct+1)/2 or ID = minID + (ct+1)/2  + (ct+1)%2 ) median, 
    (select AVG(CAST(salaryannual AS BIGINT)) from #t1 where ID = minID + ct+1 - ((ct/2+1)/2 + (ct/2+1)%2) or ID = minID + ct+1 -((ct/2+1)/2) ) q3,
    (SELECT AVG(CAST(salaryannual AS BIGINT)) FROM #t1 WHERE ID>=minID AND ID<=maxID) avgSal
FROM
(
    SELECT COUNT(*) ct, MIN(ID) minID, MAX(ID) maxID
    FROM #t1
) uniqueIDs

转换百分比计算的形式为:

pct25Wages:= Calculate(PERCENTILE.INC('table'[salaryAnnual], .25), FILTER([withSalaryCount] > 6))

之所以使用FILTER,是因为我们有一个最低要求,即至少要有7个条目具有薪水。

我的问题是如何将输入/体验转换为DAX /度量查询?

(SELECT AVG(CAST(salaryannual AS BIGINT)) FROM #t1 WHERE ID>=minID AND ID<=minID+(ct/3)) entryLevelSalary,  
(SELECT AVG(CAST(salaryannual AS BIGINT)) FROM #t1 WHERE ID>=maxID-(ct/3) AND ID<=maxID) experiencedSalary,

我尝试使用如下所示的STDDEV和AVG工资计算,但是它没有给出预期的结果,看着它,我发现它无论如何都无法正常工作:

entryWages:= [avgWages] + 3 * [StdDevWage]

1 个答案:

答案 0 :(得分:0)

因此,在将我的头撞到墙上很多次之后,这就是我完成此任务的方式。 首先,我需要按[salaryAnnual]列对集合中的行进行排名。但是,由于许多条目可以具有相同的薪水,因此我还通过使用分配给该行的uniqueID对计算进行了一些调整:

RANKX(
    'TABLE',
    'TABLE'[salaryAnnual] + ('TABLE'[ID] / 1000000000),
    ,
    ASC
    )

然后,我使用该值为我提供工资行的底部三分之一(度量[withSalaryJobCount]):

TOPN(
    1 + ( [withSalaryJobCount]/3),
    'TABLE',
    RANKX(
        'TABLE',
        'TABLE'[salaryAnnual] + ('TABLE'[ID] / 1000000000),
        ,
        ASC
        ),
    ASC
    )

最后,我只需要获取不为null的[salaryAnnual]列,只需从计算表中拉出[salaryAnnual]列即可得出平均值:

AVERAGEX(
        SELECTCOLUMNS(
            CALCULATETABLE(
                TOPN(
                    1 + ( [withSalaryJobCount]/3),
                    'TABLE',
                    RANKX(
                        'TABLE',
                        'TABLE'[salaryAnnual] + ('TABLE'[ID] / 1000000000),
                        ,
                        ASC
                        ),
                    ASC
                    ),
                FILTER(TABLE, [salaryAnnual] <> BLANK())
            ),
            "bottomThird",
            'TABLE'[salaryAnnual]
        ), [bottomThird]
    )