Reputation: 371
i have a query like this :
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'
my out put coming like this
empid status absent inout
121 1 1 1
122 0 0 0
but only i want to get result with status,absent,inout greater than 0,so how i can write where condition.
Upvotes: 1
Views: 49
Reputation: 398
Try CROSS APPLY
with a VALUES
statement, this allows you to reuse the values in subsequent joins, WHERE
clause, etc.
e.g.
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;
Once you have defined v
, you can use it like any other table in the query. I personally find these simpler to use than a CTE and more readable than a subquery. You can define expressions that depend on tables above the CROSS APPLY
and then use the values in any joins below, WHERE
clause, GROUP BY
etc.
Also, note the use of |
, the bitwise or operator, to return 1 if any of the BIT
values = 1.
Upvotes: 0
Reputation: 1269563
You could just add a condition like this:
WHERE . . . AND
(emp.status = 'terminated' or tbl.LeaveTypeId = 'a' or
(tbl.outime IS NULL AND (tbl.LeaveTypeId <> 'a' and tbl.LeaveTypeId Is null)
)
Alternatively, you could use a subquery or CTE to refer to the columns in the SELECT
.
EDIT:
The CTE looks like
with cte as (<your query here>)
select cte.*
from cte
where status = 1 or absent = 1 or inout = 1;
Upvotes: 0
Reputation: 315
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
Upvotes: 1