2016-09-28 166 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