How to write one CASE function two THEN method at the same time END AS Two NEW column depend on THEN action - sql

SELECT Emp.IntegrationFieldOne AS LocationCode, Emp.EmployeeId,
Emp.FirstName + ' '+ Emp.LastName as 'EmployeeName',
CASE WHEN ( (ORSet.Rate) =1.5 ) THEN
Sum(OT.Minutes)
END AS '1.5HRSMinutes',
CASE WHEN( ORSet.Rate =2 ) THEN
Sum(OT.Minutes)
END AS '2HRSMinutes'
FROM [CemexDB_CP_Test].[TimeAttendance].[OvertimeTransaction] OT
INNER JOIN [HumanResource].[Employee] Emp ON OT.EmployeeId = Emp.EmployeeId
INNER JOIN [CemexDB_CP_Test].[TimeAttendance].[OvertimeRateSettingDetail]
ORSet ON ORSet.OvertimeRateSettingId= OT.OvertimeType
GROUP BY Emp.EmployeeId,Emp.FirstName,Emp.LastName,Emp.IntegrationFieldOne,ORSet.Rate[!
This is Output picture click it]1
This is the out put but i want same row depend same id. but here each id has 2
row how to handle it

I think you want conditional aggregation:
SELECT Emp.IntegrationFieldOne AS LocationCode, Emp.EmployeeId,
Emp.FirstName + ' '+ Emp.LastName as EmployeeName,
SUM(CASE WHEN ORSet.Rate = 1.5 THEN OT.Minutes END) AS [1.5HRSMinutes],
SUM(CASE WHEN ORSet.Rate = 2 THEN OT.Minutes END) AS [2HRSMinutes]
FROM [CemexDB_CP_Test].[TimeAttendance].[OvertimeTransaction] OT INNER JOIN
[HumanResource].[Employee] Emp
ON OT.EmployeeId = Emp.EmployeeId INNER JOIN
[CemexDB_CP_Test].[TimeAttendance].[OvertimeRateSettingDetail]
ORSet
ON ORSet.OvertimeRateSettingId= OT.OvertimeType
GROUP BY Emp.EmployeeId, Emp.FirstName, Emp.LastName, Emp.IntegrationFieldOne;

Related

adding alias name in where condition of sql query

I have a query like this
SELECT
employee_tbl.emp_maxid,
emp_name AS 'Employee Name',
Designation_tbl.Des_Name AS Designation,
emp_LabourID,
emp_IBAN,
emp_monthlysalary AS Salary,
0 AS commission,
ISNULL(emp_monthlysalary - sum(S.Paid), emp_monthlysalary) AS Total
FROM dbo.employee_tbl
INNER JOIN dbo.Designation_tbl
ON Designation_tbl.Des_id = employee_tbl.Des_id
LEFT JOIN SalaryProcessLog_tbl S
ON S.emp_maxid = employee_tbl.emp_maxid
WHERE (emp_deleted = 0
OR emp_deleted IS NULL)
AND employee_tbl.emp_maxid NOT IN (SELECT
emp_maxid
FROM SalaryProcessLog_tbl
WHERE Balance = 0)
group by employee_tbl.emp_maxid,dbo.employee_tbl.emp_name,Designation_tbl.Des_Name,
employee_tbl.emp_LabourID, emp_IBAN,emp_monthlysalary
my out put getting like this
in my query i want to add filter result by
Where Total <> 0.. how i can do the same?
Any help is very appriciable
Wrap your query up in a derived table. Add Total condition to outer query's WHERE.
select *
from
(
SELECT
employee_tbl.emp_maxid,
emp_name AS 'Employee Name',
Designation_tbl.Des_Name AS Designation,
emp_LabourID,
emp_IBAN,
emp_monthlysalary AS Salary,
0 AS commission,
ISNULL(emp_monthlysalary - sum(S.Paid), emp_monthlysalary) AS Total
FROM dbo.employee_tbl
INNER JOIN dbo.Designation_tbl
ON Designation_tbl.Des_id = employee_tbl.Des_id
LEFT JOIN SalaryProcessLog_tbl S
ON S.emp_maxid = employee_tbl.emp_maxid
WHERE (emp_deleted = 0
OR emp_deleted IS NULL)
AND employee_tbl.emp_maxid NOT IN (SELECT
emp_maxid
FROM SalaryProcessLog_tbl
WHERE Balance = 0)
group by employee_tbl.emp_maxid,dbo.employee_tbl.emp_name,Designation_tbl.Des_Name,
employee_tbl.emp_LabourID, emp_IBAN,emp_monthlysalary
) dt
WHERE Total <> 0
To filter grouping results you should use HAVING.
SELECT
employee_tbl.emp_maxid,
emp_name AS 'Employee Name',
Designation_tbl.Des_Name AS Designation,
emp_LabourID,
emp_IBAN,
emp_monthlysalary AS Salary,
0 AS commission,
ISNULL(emp_monthlysalary - sum(S.Paid), emp_monthlysalary) AS Total
FROM dbo.employee_tbl
INNER JOIN dbo.Designation_tbl
ON Designation_tbl.Des_id = employee_tbl.Des_id
LEFT JOIN SalaryProcessLog_tbl S
ON S.emp_maxid = employee_tbl.emp_maxid
WHERE (emp_deleted = 0
OR emp_deleted IS NULL)
AND employee_tbl.emp_maxid NOT IN (SELECT
emp_maxid
FROM SalaryProcessLog_tbl
WHERE Balance = 0)
group by employee_tbl.emp_maxid,dbo.employee_tbl.emp_name,Designation_tbl.Des_Name,
employee_tbl.emp_LabourID, emp_IBAN,emp_monthlysalary
HAVING
ISNULL(emp_monthlysalary - sum(S.Paid), emp_monthlysalary) <> 0

SQL how to cross reference two unrelated tables

I need to cross reference from these 2 tables and display only the matching contindex from the first table if the contindex from the other table matches. Below is an image of what i have. Also the code is pasted below.
select t.ContIndex, t.clientcode, t.debttranname as ClientName, DebtDetService,
case when DebtTranType = 3 then 'Invoice' else 'Credit Memo' end as Type, d.amount,
REPLACE(REPLACE(REPLACE(CAST(FeeNarrative As varchar(max)),
CHAR(10) + CHAR(13), ' '), CHAR(10), ' '), CHAR(13), ' ') as Narrative
from tblTranDebtorDetail d
inner join tbltrandebtor t on t.DebtTranIndex=d.DebtTranIndex
where DebtTranDate > 'jan 1 2015' and t.debttrantype in (3,6)
and DebtDetService = 'abr reimb'
select w.contindex /*, ClientCode, ClientName, Job_Name,
case when TransTypeIndex=1 then 'Time' else 'Exp' end as Type, sum(wipamount)*/
from tblTranWIP w
inner join tblJob_Header h on h.job_idx=w.ServPeriod and h.ContIndex=w.ContIndex
inner join tblengagement e on e.ContIndex=w.ContIndex
inner join tblstaff s on s.StaffIndex=w.StaffIndex
where wipoutstanding <>0 and h.Job_Template in (99,100) and TransTypeIndex in (1,2)
--group by w.contindex, ClientCode, ClientName, Job_Name, TransTypeIndex
Basically I need to show only the top table rows that match the bottom table contindex.
Sounds like the tables are related by contindex, no? Anyhow, copy and pasting your code and adding just a little bit extra should do the trick:
select t.ContIndex, t.clientcode, t.debttranname as ClientName, DebtDetService,
case when DebtTranType = 3 then 'Invoice' else 'Credit Memo' end as Type, d.amount,
REPLACE(REPLACE(REPLACE(CAST(FeeNarrative As varchar(max)),
CHAR(10) + CHAR(13), ' '), CHAR(10), ' '), CHAR(13), ' ') as Narrative
from tblTranDebtorDetail d
inner join tbltrandebtor t on t.DebtTranIndex=d.DebtTranIndex
where DebtTranDate > 'jan 1 2015' and t.debttrantype in (3,6)
and DebtDetService = 'abr reimb'
and t.ContIndex IN
(
select w.contindex /*, ClientCode, ClientName, Job_Name,
case when TransTypeIndex=1 then 'Time' else 'Exp' end as Type, sum(wipamount)*/
from tblTranWIP w
inner join tblJob_Header h on h.job_idx=w.ServPeriod and h.ContIndex=w.ContIndex
inner join tblengagement e on e.ContIndex=w.ContIndex
inner join tblstaff s on s.StaffIndex=w.StaffIndex
where wipoutstanding <>0 and h.Job_Template in (99,100) and TransTypeIndex in (1,2)
--group by w.contindex, ClientCode, ClientName, Job_Name, TransTypeIndex
)
The additional code is the WHERE t.contindex IN (<yoursecondquery>) You could accomplish the same thing with an INNER JOIN too, but this is a quick-fix given that you already wrote out both queries seperately.
You can use an IN or EXISTS here.. You just need to alter the second query slightly to add a WHERE condition if you use EXISTS.
SELECT
t.ContIndex,
t.clientcode,
t.debttranname AS ClientName,
DebtDetService,
CASE WHEN DebtTranType = 3 THEN 'Invoice'
ELSE 'Credit Memo'
END AS Type,
d.amount,
REPLACE(REPLACE(REPLACE(CAST(FeeNarrative AS VARCHAR(MAX)),CHAR(10) + CHAR(13),' '),CHAR(10),' '),CHAR(13),' ') AS Narrative
FROM
tblTranDebtorDetail d
INNER JOIN tbltrandebtor t ON t.DebtTranIndex = d.DebtTranIndex
WHERE
DebtTranDate > 'jan 1 2015'
AND t.debttrantype IN (3,6)
AND DebtDetService = 'abr reimb'
AND EXISTS ( SELECT
w.contindex
FROM
tblTranWIP w
INNER JOIN tblJob_Header h ON h.job_idx = w.ServPeriod
AND h.ContIndex = w.ContIndex
INNER JOIN tblengagement e ON e.ContIndex = w.ContIndex
INNER JOIN tblstaff s ON s.StaffIndex = w.StaffIndex
WHERE
t.ContIndex = w.contindex -- new where clause
AND wipoutstanding <> 0
AND h.Job_Template IN (99,100)
AND TransTypeIndex IN (1,2) )

Comparing data between two tables without except operator when having null values in fields

I have this query in SQL Server which will give me the difference between two tables
SELECT * FROM dbo.emp
except
SELECT * FROM #temp1
and I get the proper result with only one record (which is correct)
But when I use a left outer join
SELECT emp.* FROM emp
LEFT JOIN #temp1 ON emp.empid = #temp1.empid
and
emp.firstname = #temp1.firstname
AND emp.lastname = #temp1.lastname
and emp.salary = #temp1.salary
and emp.dob = #temp1.dob
WHERE #temp1.empid IS NULL;
I get 39 records. Why the difference? I have mentioned all the columns in my join condition.
I know how to do this via where clause but my intention is to learn why the outer join is not working. Basically what is it that I am doing wrong
The below code works
SELECT dbo.emp.* FROM dbo.emp
JOIN #temp1 ON emp.empid = #temp1.empid
where
emp.firstname <> #temp1.firstname
or emp.lastname <> #temp1.lastname
or emp.salary <> #temp1.salary
or emp.dob <> #temp1.dob;
The outer join is presumably not working because some of the fields have NULL values.
You can emulate the except using union all and group by:
SELECT emp.*
FROM ((select 'emp' as which, empid, firstname, lastname, salary, dob
from emp
) union all
(select 'temp', empid, firstname, lastname, salary, dob
from #temp1
)
) t
group by empid, firstname, lastname, salary, dob
having sum(case when which = 'temp' then 1 else 0 end) = 0;
EDIT:
You can do this with a join using more complex conditions:
SELECT emp.*
FROM emp LEFT JOIN
#temp1
ON (emp.empid = #temp1.empid or coalesce(emp.empid, #temp1.empid) is null) and
(emp.firstname = #temp1.firstname or coalesce(emp.firstname, #temp1.firstname) is null) and
(emp.lastname = #temp1.lastname or coalesce(emp.lastname, #temp1.lastname) is null) and
(emp.salary = #temp1.salary or coalesce(emp.salary, #temp1.salary) is null) and
(emp.dob = #temp1.dob or or coalesce(emp.dob, #temp1.dob ) is null)
WHERE #temp1.empid IS NULL;

how to limit row number to one unique row in SQL query?

I need to limit the row number to one unique row in SQL query. Here's sample data to recognize what I'm talking about:
john doe 3000 fog horn drive , ky 40444
john doe 3001 merry lane , ky 40484
I want to return the first one in the list here's my query :
Select
DISTINCT p.personID, e.citizenship,
rtrim(i.lastname + CASE WHEN i.suffix IS NULL THEN '' ELSE ' ' + i.suffix END) + ', ' + i.firstname + (CASE WHEN i.middlename IS NULL THEN '' ELSE ' ' + i.middlename END) StuName,
e.grade, i.gender, p.studentNumber, e.citizenship, e.adult, i.birthdate,
e.disability1, e.disability2, ad.city, e.displacedHomemaker, e.homeSchooled,
e.localStudentNumber, e.migrant, e.modifiedDate, e.modifiedByID,
rtrim(Staff.lastname + CASE WHEN Staff.suffix IS NULL THEN '' ELSE ' ' + Staff.suffix END) + ', ' + Staff.firstname + (CASE WHEN Staff.middlename IS NULL THEN '' ELSE ' ' + Staff.middleName END) Staffname,
Staff.personID Staffid, i.lastname, i.firstname, i.middlename, i.ssn,
ad.phone, ad.state, ad.zip, ad.addressLine1
FROM
Person p
LEFT join
Enrollment e ON e.personID = p.personID And isnull(e.noshow, 0) = 0
LEFT join
EnrollmentKY ky ON ky.enrollmentID = e.enrollmentID
LEFT join
[Identity] i ON i.identityID = p.currentIdentityID And i.personID = p.personID
INNER join
Calendar c ON c.calendarID = e.calendarID
INNER join
SchoolYear sy ON sy.endYear = c.endYear AND sy.active = 1
JOIN
staffMember Staff ON Staff.personID = e.modifiedByID
--join view_students s ON s.personID = i.personID
left join
v_MailingAddress ad ON ad.personID = i.personID And ad.relatedBy = 'household'
And ad.endDate IS NULL And isnull(ad.secondary, 0) = 0
order by
i.lastname, i.firstname, i.middlename
edit: need to only pick first row in SQL code because I have a problem with people that have multiple addresses it puts two rows for them and i only need first row of data for the person that has multiple addresses.
If the personId is distinct for each of the records and they just have a different address, then you can add a field for the row_number() and then only select the records where the row_number = 1:
select *
from
(
Select p.personID,
e.citizenship,
rtrim(i.lastname + CASE WHEN i.suffix IS NULL THEN '' ELSE ' ' + i.suffix END) + ', ' + i.firstname + (CASE WHEN i.middlename IS NULL THEN '' ELSE ' ' + i.middlename END) StuName,
e.grade,
i.gender,
p.studentNumber,
e.citizenship,
e.adult,
i.birthdate,
e.disability1,
e.disability2,
ad.city,
e.displacedHomemaker,
e.homeSchooled,
e.localStudentNumber,
e.migrant,
e.modifiedDate,
e.modifiedByID,
rtrim(Staff.lastname + CASE WHEN Staff.suffix IS NULL THEN '' ELSE ' ' + Staff.suffix END) + ', ' + Staff.firstname + (CASE WHEN Staff.middlename IS NULL THEN '' ELSE ' ' + Staff.middleName END) Staffname,
Staff.personID Staffid,
i.lastname,
i.firstname,
i.middlename,
i.ssn,
ad.phone,
ad.state,
ad.zip,
ad.addressLine1,
row_number() over(partition by p.personid order by p.personid) rn -- add this field
FROM Person p
LEFT join Enrollment e
ON e.personID = p.personID
And isnull(e.noshow,0)=0
LEFT join EnrollmentKY ky
ON ky.enrollmentID = e.enrollmentID
LEFT join [Identity] i
ON i.identityID = p.currentIdentityID
And i.personID = p.personID
INNER join Calendar c
ON c.calendarID = e.calendarID
INNER join SchoolYear sy
ON sy.endYear = c.endYear
AND sy.active = 1
JOIN staffMember Staff
ON Staff.personID = e.modifiedByID
--join view_students s ON s.personID = i.personID
left join v_MailingAddress ad
ON ad.personID = i.personID
And ad.relatedBy = 'household'
And ad.endDate IS NULL
And isnull(ad.secondary,0)=0
) x
where x.rn = 1
order by x.lastname, x.firstname, x.middlename
Try using the LIMIT to limit the no. of outputs.
Eg:
SELECT COLUMN_NAME
FROM TABLE
ORDER BY CONDITION
LIMIT NO_OF_ROWS;
Have you tried using a "GROUP BY" clause instead of the DISTINCT keyword?
Also, what about a Sub-Query? If I were writing this type of thing I'd use a sproc and create a temporary table.
Edit: Deleted original answer as question was changed and original answer is not the way to go with changed question.
Suggest GROUP BY clause per Neil Hoskins.

Query for logistic regression, multiple where exists

A logistic regression is a composed of a uniquely identifying number, followed by multiple binary variables (always 1 or 0) based on whether or not a person meets certain criteria. Below I have a query that lists several of these binary conditions. With only four such criteria the query takes a little longer to run than what I would think. Is there a more efficient approach than below? Note. tblicd is a large table lookup table with text representations of 15k+ rows. The query makes no real sense, just a proof of concept. I have the proper indexes on my composite keys.
select patient.patientid
,case when exists
(
select c.patientid from tblclaims as c
inner join patient as p on p.patientid=c.patientid
and c.admissiondate = p.admissiondate
and c.dischargedate = p.dischargedate
where patient.patientid = p.patientid
group by c.patientid
having count(*) > 1000
)
then '1' else '0'
end as moreThan1000
,case when exists
(
select c.patientid from tblclaims as c
inner join patient as p on p.patientid=c.patientid
and c.admissiondate = p.admissiondate
and c.dischargedate = p.dischargedate
where patient.patientid = p.patientid
group by c.patientid
having count(*) > 1500
)
then '1' else '0'
end as moreThan1500
,case when exists
(
select distinct picd.patientid from patienticd as picd
inner join patient as p on p.patientid= picd.patientid
and picd.admissiondate = p.admissiondate
and picd.dischargedate = p.dischargedate
inner join tblicd as t on t.icd_id = picd.icd_id
where t.descrip like '%diabetes%' and patient.patientid = picd.patientid
)
then '1' else '0'
end as diabetes
,case when exists
(
select r.patientid, count(*) from patient as r
where r.patientid = patient.patientid
group by r.patientid
having count(*) >1
)
then '1' else '0'
end
from patient
order by moreThan1000 desc
I would start by using subqueries in the from clause:
select q.patientid, moreThan1000, moreThan1500,
(case when d.patientid is not null then 1 else 0 end),
(case when pc.patientid is not null then 1 else 0 end)
from patient p left outer join
(select c.patientid,
(case when count(*) > 1000 then 1 else 0 end) as moreThan1000,
(case when count(*) > 1500 then 1 else 0 end) as moreThan1500
from tblclaims as c inner join
patient as p
on p.patientid=c.patientid and
c.admissiondate = p.admissiondate and
c.dischargedate = p.dischargedate
group by c.patientid
) q
on p.patientid = q.patientid left outer join
(select distinct picd.patientid
from patienticd as picd inner join
patient as p
on p.patientid= picd.patientid and
picd.admissiondate = p.admissiondate and
picd.dischargedate = p.dischargedate inner join
tblicd as t
on t.icd_id = picd.icd_id
where t.descrip like '%diabetes%'
) d
on p.patientid = d.patientid left outer join
(select r.patientid, count(*) as cnt
from patient as r
group by r.patientid
having count(*) >1
) pc
on p.patientid = pc.patientid
order by 2 desc
You can then probably simplify these subqueries more by combining them (for instance "p" and "pc" on the outer query can be combined into one). However, without the correlated subqueries, SQL Server should find it easier to optimize the queries.
Example of left joins as requested...
SELECT
patientid,
ISNULL(CondA.ConditionA,0) as IsConditionA,
ISNULL(CondB.ConditionB,0) as IsConditionB,
....
FROM
patient
LEFT JOIN
(SELECT DISTINCT patientid, 1 as ConditionA from ... where ... ) CondA
ON patient.patientid = CondA.patientID
LEFT JOIN
(SELECT DISTINCT patientid, 1 as ConditionB from ... where ... ) CondB
ON patient.patientid = CondB.patientID
If your Condition queries only return a maximum one row, you can simplify them down to
(SELECT patientid, 1 as ConditionA from ... where ... ) CondA