adding alias name in where condition of sql query - sql

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

Related

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

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;

SQL Where in for Many to Many Join Table

I have the following (moderately epic query) which I have been writing
Select *
from
(Select
Salutation,
FirstName, LastName, FullName,
PhotoUrl, CountryCode, Email, Birthday,
Gender, HomePhone, M.MemberId, IDType, JoinDate,
HomeLocation, HomeLocationId,
Region.Name as RegionName,
M.MembershipId,
coalesce(case
when Package.PackageIsReoccuring = 1 then 'Recurring'
when Package.PackageIsSession = 1 then 'Paid In Full'
when membership.TotalPrice = 0 then 'Free'
when Package.PackagePayInFull = 1 then 'Paid In Full'
end, 'N/A') as PackageTerm,
coalesce(PackageType.Name, 'N/A') as PackageType,
coalesce(membershipstate.name, 'N/A') as MembershipState,
MembershipStartDate =
case
when membership.StartDate IS NULL
then ''
else CONVERT(varchar(50),membership.StartDate)
end,
MembershipEndDate =
case
when membership.EndDate IS NULL
then ''
else CONVERT(varchar(50),membership.EndDate)
end,
Region.Id as RegionId
from
(select
AspNetUsers.Salutation,
AspNetUsers.FirstName, AspNetUsers.LastName,
CONCAT (AspNetUsers.FirstName, ' ', AspNetUsers.LastName) as FullName,
AspNetUsers.PhotoUrl, AspNetUsers.CountryCode, AspNetUsers.Email,
AspNetUsers.Birthday, AspNetUsers.Gender,
AspNetUsers.HomePhone as HomePhone,
Member.Id as MemberId, Member.IDType, Member.JoinDate,
HomeLocation.Name as HomeLocation,
HomeLocation.Id as HomeLocationId,
(case when (select top 1 id from membership where membership.memberid = Member.id and (membership.membershipstateid = 1 or membership.membershipstateid = 6)) IS NULL Then (select top 1 id from membership where membership.memberid = Member.id order by membership.enddate desc) ELSE (select top 1 id from membership where membership.memberid = Member.id and (membership.membershipstateid = 1 or membership.membershipstateid = 6)) END) as MembershipId
from
AspNetUsers
join
Member on AspNetUsers.id = Member.aspnetuserid
join
Location as HomeLocation on Member.HomeLocationId = HomeLocation.id) as M
left join
Membership on M.MembershipId = Membership.Id
left join
Package on Membership.packageid = Package.Id
left join
PackageType on Package.packagetypeid = PackageType.Id
left join
MembershipState on Membership.membershipstateid = MembershipState.Id
left join
Region on Membership.RegionId = Region.Id) as Result
order by
Result.LastName desc
I have a final join table which I want to use which is a many-to-many relationship on Region. Region has a Join Table (RegionLocations) which is a join between Region and Locations.
With my query below I would like to get all results where the HomeLocationId = 2 OR he has a LocationId (from RegionLocations) which also contains 2. The RegionId is a nullable value and isn't always populated.
How can I get this? Do I need to return values into a CSV? This final hurdle is a battle..
Thanks
You could extend this:
left join
Region on Membership.RegionId = Region.Id) as Result
to this:
left join
Region on Membership.RegionId = Region.Id
where M.HomeLocationId = 2
or Region.Id in (select RegionId from RegionLocation where LocationId = 2)
) as Result
Some other remarks about your query:
The fields MembershipStartDate and MembershipEndDate can be evaluated more concisely as:
COALESCE(CONVERT(varchar(50),membership.StartDate), '') as MembershipStartDate,
COALESCE(CONVERT(varchar(50),membership.EndDate), '') as MembershipEndDate,
The inner field MembershipId is defined with three sub-queries in a case when, which can be shortened to just one query. It uses in instead of an or condition, and puts it in the order by clause in a way that gets the priority right:
(select top 1 id
from membership
where membership.memberid = Member.id
order by case when membership.membershipstateid in (1,6) then 0 else 1 end,
membership.enddate desc
) as MembershipId
Finally, if you just have an outer query that performs a select * from (...) order by, then why not skip that outer query and perform that order by on the inner query direcly?

Not able to Group table on percentage Column

Edit : Database - SQL server 2014
I am trying to Calculate Daily Percentage Of Student "Present" like this :
But I Getting Result like this :
Only while Calculating Percentage I am not able to group Rows based on Class.
With Out percentage Calculation , Result are grouping Fine
My Student Attendance table..
This is My Query...
SELECT CM.ClassName ,SB.SubjectName ,
count(sa.Day14) Total,
sum(case when sa.Day14 = 'P' then 1 else 0 end) Present,
sum(case when sa.Day14 = 'A' then 1 else 0 end) Absent,
(SELECT CAST(
CASE
WHEN count(sa.Day14) = 0
THEN 0
ELSE (sum(case when Day14 = 'P' then 1 else 0 end)* 100)/(count(Day14))
END AS nvarchar(100))) as [Present%],
AttendanceDate from studentattendance SA
inner join studentmaster SM on SA.StudentID = SM.ID
join ProfessorMaster p on SA.ProfessorID = p.Id
join Classmaster CM on SA.ClassID = CM.ID
inner join SubjectMaster SB on SA.SubjectID = SB.ID
where
sa.ProfessorID = '36' and sa.AttendanceDate = '2015-09' and SA.AdminId ='29'
group by CM.ClassName, SB.SubjectName, SA.AttendanceDate,sa.Day14
What I am Missing ?
The problem with your query is that you are doing a count on Day14 group by Day14. With this you can't do sum in the same query as you specified a group by already. So you have to split your query.
Lets say your attendance table looks like this for a particular subject/class on a particular day.
StudentID Day14
46 A
47 P
48 P
If you are using Oracle,then create a CTE. Else create a view to count 'A' and 'P'.
select distinct(Day14), count(*) as AorP from yourTable group by Day14
Now create another CTE/view to get the total sum and percent like below
select DAY14, AORP*100/(select sum(AORP) as yourView from tbl2) as percentage from tbl2
This will give you result like
Day14 PERCENTAGE
P 66.67
A 33.33
Now join this view to your main query to get PERCENTAGE based for Present or Absent. You can also use this view as an inline query (like
select col1,(select Day14 as AbsentPercent from newView where id=something and Day14='A')
Note: This view is just for example, You have to add at least 1 unique identifier to join to your main table later. To capture missing entries, use appropriate outer join.
I got much Smaller Solution :) ...
Calculate Percentage in Datatable[Or any ResultSet in Code] ...
My Query (Not calculating Percentage )
SELECT CM.ClassName ,SB.SubjectName ,
count(sa.Day14) Total,
sum(case when sa.Day14 = 'P' then 1 else 0 end) Present,
sum(case when sa.Day14 = 'A' then 1 else 0 end) Absent,
'' [Present%] ,
AttendanceDate from studentattendance SA
inner join studentmaster SM on SA.StudentID = SM.ID
join ProfessorMaster p on SA.ProfessorID = p.Id
join Classmaster CM on SA.ClassID = CM.ID
inner join SubjectMaster SB on SA.SubjectID = SB.ID
where
sa.ProfessorID = '36' and sa.AttendanceDate = '2015-09' and SA.AdminId ='29'
group by CM.ClassName, SB.SubjectName, SA.AttendanceDate,sa.Day14
and in DataTable ......
foreach (DataRow dr in ds.Tables[0].Rows)
{
var Total = Convert.ToInt32(Convert.ToDouble(dr["Total"]));
var Present = Convert.ToInt32(Convert.ToDouble(dr["Present"]));
dr["Present%"] = (Present * 100) / Total;
}

Sum of resulting set of rows in SQL

I've got the following query:
SELECT DISTINCT CU.permit_id, CU.month, /*CU.year,*/ M.material_id, M.material_name, /*MC.chemical_id, C.chemical_name,
C.precursor_organic_compound, C.non_precursor_organic_compound,*/
/*MC.chemical_percentage,*/
POC_emissions =
CASE
WHEN (C.precursor_organic_compound = 'true')
THEN (CU.chemical_usage_lbs / CU.material_density) * M.VOC
ELSE 0
END,
NON_POC_emissions =
CASE
WHEN (C.non_precursor_organic_compound = 'true')
THEN CU.chemical_usage_lbs * (MC.chemical_percentage / 100)
ELSE 0
END
FROM material M
LEFT OUTER JOIN material_chemical MC ON MC.material_id = M.material_id
LEFT OUTER JOIN chemical_usage CU ON CU.material_id = MC.material_id
LEFT OUTER JOIN chemical C ON C.chemical_id = MC.chemical_id
WHERE (CU.month >=1 AND CU.month <= 2)
AND CU.year = 2013
AND M.material_id = 52
--AND CU.permit_id = 2118
--GROUP BY CU.permit_id, M.material_id, M.material_name, CU.month, MC.chemical_id, MC.chemical_id, C.chemical_name, C.precursor_organic_compound, C.non_precursor_organic_compound
--ORDER BY C.chemical_name ASC
Which returns:
But what I need is to return one row per month per material adding up the values of POC per month and NON_POC per month.
So, I should end up with something like:
Month material_id material_name POC NON_POC
1 52 Krylon... 0.107581 0.074108687
2 52 Krylon... 0.143437 0.0988125
I tried using SUM but it sums up the same result multiple times:
SELECT /*DISTINCT*/ CU.permit_id, CU.month, /*CU.year,*/ M.material_id, M.material_name, /*MC.chemical_id, C.chemical_name,
C.precursor_organic_compound, C.non_precursor_organic_compound,*/
--MC.chemical_percentage,
POC_emissions = SUM(
CASE
WHEN (C.precursor_organic_compound = 'true')
THEN (CU.chemical_usage_lbs / CU.material_density) * M.VOC
ELSE 0
END),
NON_POC_emissions = SUM(
CASE
WHEN (C.non_precursor_organic_compound = 'true')
THEN CU.chemical_usage_lbs * (MC.chemical_percentage / 100)
ELSE 0
END)
FROM material M
LEFT OUTER JOIN material_chemical MC ON MC.material_id = M.material_id
LEFT OUTER JOIN chemical_usage CU ON CU.material_id = MC.material_id
LEFT OUTER JOIN chemical C ON C.chemical_id = MC.chemical_id
WHERE M.material_id = 52
--AND CU.permit_id = 187
AND (CU.month >=1 AND CU.month <= 2)
AND CU.year = 2013
GROUP BY CU.permit_id, M.material_id, M.material_name, CU.month/*, CU.year, MC.chemical_id, C.chemical_name, C.precursor_organic_compound, C.non_precursor_organic_compound*/
--ORDER BY C.chemical_name ASC
The first query has a DISTINCT clause. What is the output without the DISTINCT clause. I suspect you have more rows than shows in your screenshot.
Regardless, you could try something like this to get the desired result.
select permit_id, month, material_id, material_name,
sum(poc_emissions), sum(non_poc_emissions)
from (
SELECT DISTINCT CU.permit_id, CU.month, M.material_id, M.material_name,
POC_emissions =
CASE
WHEN (C.precursor_organic_compound = 'true')
THEN (CU.chemical_usage_lbs / CU.material_density) * M.VOC
ELSE 0
END,
NON_POC_emissions =
CASE
WHEN (C.non_precursor_organic_compound = 'true')
THEN CU.chemical_usage_lbs * (MC.chemical_percentage / 100)
ELSE 0
END
FROM material M
LEFT OUTER JOIN material_chemical MC ON MC.material_id = M.material_id
LEFT OUTER JOIN chemical_usage CU ON CU.material_id = MC.material_id
LEFT OUTER JOIN chemical C ON C.chemical_id = MC.chemical_id
WHERE (CU.month >=1 AND CU.month <= 2)
AND CU.year = 2013
AND M.material_id = 52
) main
group by permit_id, month, material_id, material_name
Explanation
Since the results you retrieved by doing a DISTINCT was consider source-of-truth, I created an in-memory table by making it a sub-query. However, this subquery must have a name of some kind...whatever name. I gave it a name main. Subqueries look like this:
select ... from (sub-query) <give-it-a-table-name>
Simple Example:
select * from (select userid, username from user) user_temp
Advanced Example:
select * from (select userid, username from user) user_temp
inner join (select userid, sum(debits) as totaldebits from debittable) debit
on debit.userid = user_temp.userid
Notice how user_temp alias for the subquery can be used as if the sub-query was a real table.
Use above query in subquery and group by (month) and select sum(POC_emissions) and sum(NON_POC_emissions )

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;