2016-09-28 125 views
1

我有这样的查询:过滤器的SQL查询的SQL Server

SELECT 
    tbl.EmpID, 
    CASE 
    WHEN emp.status = 'terminated' THEN CONVERT(bit, 1) 
    ELSE CONVERT(bit, 0) 
    END AS 'Status', 
    CASE 
    WHEN tbl.LeaveTypeId = 'a' THEN CONVERT(bit, 1) 
    ELSE CONVERT(bit, 0) 
    END AS 'Absent', 
    CASE 
    WHEN (tbl.outime IS NULL) AND 
     (tbl.LeaveTypeId <> 'a' and tbl.LeaveTypeId Is null) THEN CONVERT(bit, 1) 
    ELSE CONVERT(bit, 0) 
    END AS 'InOut', 
    emp.EmpFullName, 
    tbl.P_Date, 
    cmp.cmplogo, 
    emp.nation_id, 
    emp.dept_id, 
    emp.desig_id AS 'designation_id', 
    emp.tradecd, 
    emp.comp_id, 
    emp.section_id, 
    emp.location_id, 
    emp.emplcatgry 
FROM tblattendance tbl 
INNER JOIN EMPLOYEEs emp 
    ON emp.empid = tbl.empid 
INNER JOIN Company cmp 
    ON cmp.comp_id = emp.comp_id 
WHERE CONVERT(varchar(10), tbl.p_date, 112) BETWEEN '20160901' AND '20160902' 

我出来就把未来类似这样的

empid status absent inout 
121  1  1  1 
122  0  0  0 

但只有我想用状态造成的,不存在,inout大于0,所以我怎么写条件。

+0

不知道是什么用意,但这样的:'(tbl.LeaveTypeId <> 'a' 和tbl.LeaveTypeId为空)'没有任何意义,因为如果它是NULL,它永远不能与chars比较。应该是OR而不是AND? – Beth

回答

0

你可以只添加一个条件是这样的:

WHERE . . . AND 
     (emp.status = 'terminated' or tbl.LeaveTypeId = 'a' or 
     (tbl.outime IS NULL AND (tbl.LeaveTypeId <> 'a' and tbl.LeaveTypeId Is null) 
    ) 

或者,你可以使用子查询或CTE来引用列在SELECT

编辑:

的CTE看起来像

with cte as (<your query here>) 
select cte.* 
from cte 
where status = 1 or absent = 1 or inout = 1; 
+0

如何使用CTE? – user3262364

0

VALUES声明试试CROSS APPLY,这可以让你在后续加入,WHERE条款重用值等

例如

SELECT 
    tbl.EmpID, 
    v.Status, 
    v.Absent, 
    v.InOut, 
    emp.EmpFullName, 
    tbl.P_Date, 
    cmp.cmplogo, 
    emp.nation_id, 
    emp.dept_id, 
    emp.desig_id AS 'designation_id', 
    emp.tradecd, 
    emp.comp_id, 
    emp.section_id, 
    emp.location_id, 
    emp.emplcatgry 
FROM tblattendance tbl 
INNER JOIN EMPLOYEEs emp 
    ON emp.empid = tbl.empid 
INNER JOIN Company cmp 
    ON cmp.comp_id = emp.comp_id 
CROSS APPLY (
    VALUES (
    CASE 
    WHEN emp.status = 'terminated' THEN CONVERT(bit, 1) 
    ELSE CONVERT(bit, 0) 
    END, 
    CASE 
    WHEN tbl.LeaveTypeId = 'a' THEN CONVERT(bit, 1) 
    ELSE CONVERT(bit, 0) 
    END, 
    CASE 
    WHEN (tbl.outime IS NULL) AND 
     (tbl.LeaveTypeId <> 'a' and tbl.LeaveTypeId Is null) THEN CONVERT(bit, 1) 
    ELSE CONVERT(bit, 0) 
    END 
) 
) v (Status, Absent, InOut) 
WHERE CONVERT(varchar(10), tbl.p_date, 112) BETWEEN '20160901' AND '20160902' 
    AND (v.Status | v.Absent | v.InOut) = 1; 

一旦你定义了v,你可以使用它像查询任何其他表。我个人发现这些比CTE更简单,比子查询更易读。您可以定义取决于CROSS APPLY上述表的表达式,然后使用这些值在以下任何连接,WHERE条款,GROUP BY

另外,还要注意使用|,按位或操作,如果有的话,返回1在BIT值= 1

1
SELECT S.* FROM (SELECT tbl.EmpID, CASE 
    WHEN emp.status = 'terminated' THEN CONVERT(bit, 1) 
    ELSE CONVERT(bit, 0) END AS 'Status', CASE 
    WHEN tbl.LeaveTypeId = 'a' THEN CONVERT(bit, 1) 
    ELSE CONVERT(bit, 0) END AS 'Absent', CASE 
    WHEN (tbl.outime IS NULL) AND 
     (tbl.LeaveTypeId <> 'a' and tbl.LeaveTypeId Is null) THEN CONVERT(bit, 1) 
    ELSE CONVERT(bit, 0) END AS 'InOut', emp.EmpFullName, tbl.P_Date, cmp.cmplogo, emp.nation_id, emp.dept_id, 
emp.desig_id AS 'designation_id', emp.tradecd, emp.comp_id, 
emp.section_id, emp.location_id, emp.emplcatgry FROM tblattendance 
tbl INNER JOIN EMPLOYEEs emp ON emp.empid = tbl.empid INNER JOIN 
Company cmp ON cmp.comp_id = emp.comp_id WHERE CONVERT(varchar(10), 
tbl.p_date, 112) BETWEEN '20160901' AND '20160902') S WHERE 
S.Status>0 OR S.Absent>0 OR S.InOut>0