选择标志以指示访问sql中底部10%的每个字段

时间:2017-02-06 14:22:26

标签: sql ms-access

我有一张表格,列出了一系列绩效领域(KPI)中每位员工的得分。我编写了一个返回这些分数的查询以及“标记”字段,表明每个业务领域的每个KPI是否位于最低10%。该查询正在运行,但似乎过于复杂(下面的示例显示了3个KPI,但实际版本还有更多):

SELECT [Employee Number], [Full Name], [Business Area], 

[Absence],
IIF([Employee Number] in (
    SELECT TOP 10 PERCENT [Employee Number]
    FROM tblKPIScores as a
    WHERE a.[Business Area] = tblKPIScores.[Business Area]
    ORDER BY Absence DESC
),"Y","N") AS AbsenceFlag,

[Complaints], 
IIF([Employee Number] in (
    SELECT TOP 10 PERCENT [Employee Number]
    FROM tblKPIScores as b
    WHERE b.[Business Area] = tblKPIScores.[Business Area]
    ORDER BY Complaints DESC
),"Y","N") AS ComplaintsFlag,

[Service Time],
IIF([Employee Number] in (
    SELECT TOP 10 PERCENT [Employee Number]
    FROM tblKPIScores as c
    WHERE c.[Business Area] = tblKPIScores.[Business Area]
    ORDER BY [Service Time] DESC
),"Y","N") AS [Service Time Flag]

FROM tblKPIScores

我想知道是否有更有效的方法来编写此代码而不必为每个KPI单独执行子查询?

1 个答案:

答案 0 :(得分:1)

考虑使用派生表,每个KPI一个。您甚至可以将每个派生表保存为单独的已保存查询,替换SELECT子句中的嵌套LEFT JOIN语句。这将是一个更有效的解决方案,因为您不再为每个行值运行嵌套在IIF()中的相关子查询。

注意:Access SQL需要为每个JOIN parings包装括号;因此,对于复杂查询,最好在查询的设计视图中预先设计连接:

SELECT t.[Employee Number], t.[Full Name], t.[Business Area], 
       t.[Absence], IIF(a.AbsenceEmpNum IS NOT NULL, 'Y', 'N') AS AbsenceFlag,
       t.[Complaints],  IIF(a.ComplaintsEmpNum IS NOT NULL, 'Y', 'N') AS ComplaintsFlag,
       t.[Service Time], IIF(a.ServiceTimeEmpNum IS NOT NULL, 'Y', 'N') AS ServiceTimeFlag

FROM ((tblKPIScores t

LEFT JOIN
   (SELECT TOP 10 PERCENT sub.[Employee Number] As AbsenceEmpNum
    FROM tblKPIScores as sub
    ORDER BY sub.Absence DESC) AS a
ON t.[Employee Number] = a.AbsenceEmpNum)

LEFT JOIN
   (SELECT TOP 10 PERCENT sub.[Employee Number] As ComplaintsEmpNum
    FROM tblKPIScores as sub
    ORDER BY sub.Complaints DESC) AS c
ON t.[Employee Number] = c.ComplaintsEmpNum)

LEFT JOIN
   (SELECT TOP 10 PERCENT sub.[Employee Number] As ServiceTimeEmpNum
    FROM tblKPIScores as sub
    ORDER BY sub.[Service Time] DESC) AS s
ON t.[Employee Number] = s.ServiceEmpNum