获取数据过滤器所需的TSQL Hack
UI(在报告显示之前)显示一个具有获取数据过滤器所需的TSQL Hack,tsql,filtering,append,Tsql,Filtering,Append,UI(在报告显示之前)显示一个具有 (ID=0)。所有组织单位 (ID=4)小时 (ID=5)。开发 我需要: 能够显示(4)+(5)的数据,如果 已选择(0) 如果选择了人力资源或开发,则仅限(4)或(5) 查找组合代码(所选内容将在下面的查询中提供参数。) 报表数据行查询 设置CONCAT\u NULL\u输出值\u NULL关闭 将@EmpID声明为int; 将@OrganizationUnit声明为int; 声明@StartDate为日期时间; 将@EndDate声明为da
- (ID=0)。所有组织单位
- (ID=4)小时
- (ID=5)。开发
查找组合代码(所选内容将在下面的查询中提供参数。)
报表数据行查询
设置CONCAT\u NULL\u输出值\u NULL关闭
将@EmpID声明为int;
将@OrganizationUnit声明为int;
声明@StartDate为日期时间;
将@EndDate声明为datetime;
设置@EmpID=?;
设置@StartDate=?;
设置@EndDate=?;
设置@OrganizationUnit=?;
挑选
员工代码,
Employee.Name1+''+Employee.Name2+''+Employee.Name3+''+Employee.Name4+''+Employee.Name5作为全名,
雇员组织单位,
ContractType.Name,
EmployeeContract.StartDate,
EmployeeContract.EndDate
来自员工内部加入(合同类型内部加入员工合同
ON ContractType.ID=EmployeeContract.ContractType)
ON Employee.ID=EmployeeContract.Employee
其中(Employee.ID=@EmpID或@EmpID=0)
及
(Employee.OrganizationUnit=@OrganizationUnit或@OrganizationUnit=0)
而不是((EndDate<@StartDate或StartDate>@EndDate));
从外表上看,我有什么办法可以做到吗?0=0将显示来自其他数据库的所有数据 部门也是
任何人:-o?像这样的东西应该有用
Where (Employee.OrganizationUnit = case when @OrganizationUnit=0 then 4 else @OrganizationUnit end OR case when @OrganizationUnit=0 then 5 else @OrganizationUnit end)
怎么样
WHERE (Employee.ID = @EmpID OR @EmpID=0)
AND
(Employee.OrganizationUnit BETWEEN ISNULL(NULLIF(@OrganizationUnit,0),0) AND ISNULL(NULLIF(@OrganizationUnit,0),99))
AND NOT((EndDate < @StartDate or StartDate > @EndDate));
其中(Employee.ID=@EmpID或@EmpID=0)
及
(Employee.OrganizationUnit介于ISNULL(NULLIF(@OrganizationUnit,0),0)和ISNULL(NULLIF(@OrganizationUnit,0,99))之间)
而不是((EndDate<@StartDate或StartDate>@EndDate));
试试这个,它应该在查询中使用索引
DECALRE @FilterValues (FilterValue int not null primary key)
IF @Param=0
BEGIN
INSERT INTO @FilterValues VALUES (4)
INSERT INTO @FilterValues VALUES (5)
END
ELSE ID @PAram IS NOT NULL
BEGIN
INSERT INTO @FilterValues VALUES (@Param)
END
SELECT
....
FROM YourTable y
INNER JOIN @FilterValues f ON y.Value=f.Value
WHERE .....
首先,您的查找组合代码可以收紧一点:
-- the FROM clause was superfluous
SELECT 0 AS ID,'All Org' AS Name
UNION ALL
-- the two-part identifiers were superfluous (only one table)
SELECT ID, Name
FROM DP_ORG_OrganizationUnit
WHERE Code IN ('HR','DEV')
对于报告查询,最简单的形式是:
WHERE
((@OrganizationUnit > 0 AND Employee.OrganizationUnit = @OrganizationUnit) OR
(@OrganizationUnit = 0 AND Employee.OrganizationUnit IN (4,5)))
KM的版本可以运行,但此查询不需要临时表…
SELECT *
FROM Employee
WHERE (
@OrganizationUnit = 0
OR
(
@OrganizationUnit <> 0
AND
Employee.OrganizationUnit = @OrganizationUnit
)
)
选择*
来自员工
在哪里(
@组织单元=0
或
(
@组织单元0
及
Employee.OrganizationUnit=@OrganizationUnit
)
)
了解is ISNULL()和COALESCE(),因为“SET CONCAT\u NULL\u YIELDS\u NULL OFF”在将来会消失。当你在WHERE,lookout表扫描中放置KEY=x或KEY=y时,在一百万行表上这样做,你会希望在扫描整个内容时有一个临时表!我想相信你,但是你能告诉我为什么临时表更好吗?我在一个500k行的表上进行了测试,结果表明我的方法大约快了5%到10%。也许随着行数越来越大,我的效率会越来越低?我真的很好奇哪一个更好。我的查询计划是:1。选择成本2%2。过滤成本18%3。索引扫描成本为80%。您的查询计划显示:1。选择成本0%2。散列匹配(内部联接)成本为53%3a。聚集索引扫描@FilterValue的成本为1%3b。索引扫描花费46%您的版本将永远不会使用索引,只使用扫描。对于我的版本,它将取决于Employee.OrganizationUnit列中有多少唯一值(并且有一个索引),如果它将扫描的表中的行没有多少不同的值。但是,如果相对于行数(一个好的索引)有许多不同的值,它将使用该索引。在您的示例中,它不是一个好的索引,并进行了扫描。
WHERE
((@OrganizationUnit > 0 AND Employee.OrganizationUnit = @OrganizationUnit) OR
(@OrganizationUnit = 0 AND Employee.OrganizationUnit IN (4,5)))
SELECT *
FROM Employee
WHERE (
@OrganizationUnit = 0
OR
(
@OrganizationUnit <> 0
AND
Employee.OrganizationUnit = @OrganizationUnit
)
)