How to sum the values of two rows in sql server - sql-server

SELECT (
(SUM(t_price) - SUM(a_dvpay)) - (
SELECT SUM(inst_amount)
FROM installment
WHERE uid = user_info.uid
)
) AS remaining
FROM user_info
WHERE faculty_id = #faculty_id
GROUP BY uid;
This SQL query return the remaining result in multiple rows. I want to sum the values of remaining as Total remaining.
SQL Query Result

Remove the Group By clause.
SELECT ((sum(t_price) - sum(a_dvpay))-(select sum(inst_amount) from installment where uid=user_info.uid)) as remaining FROM user_info WHERE (faculty_id = #faculty_id)**strong text**

So it will be the sum of the amount(s) inside installment table, and I assume that not all members under a given faculty_id has a record there. In order to cater that, I used COALESCE to handle NULLS in the installment table:
SELECT ui.uid,
(SUM(ui.t_price) - SUM(ui.a_dvpay)) - SUM(COALESCE(i.inst_amount, 0)) `remaining`
FROM user_info ui
LEFT JOIN installment i ON i.uid = ui.uid
WHERE faculty_id = #faculty_id
GROUP BY ui.uid;

I found a solution that return what you needed:
SELECT SUM(remaining) FROM (
SELECT sum(t_price - a_dvpay) as remaining
FROM user_info
WHERE faculty_id = 1
UNION
SELECT -SUM(COALESCE(inst_amount,0))
FROM installment inst
WHERE uid IN (SELECT DISTINCT user_info.uid FROM user_info WHERE faculty_id = 1)
) x
Test it: http://sqlfiddle.com/#!9/e6d341/11

Related

How to use ##ROWCOUNT in a SQL Server derived table?

I have multiple join (left join) derived tables in my query and one of them returns an empty result set which gives me a problem in my WHERE clause.
WHERE Clause:
WHERE (ISNULL(BalanceThis.Balance,0) + ISNULL(RL.Balance,0) + ISNULL(OtherPayThis.Balance,0) + ISNULL(RUPBalThis.Balance,0)) <> 0
Query:
LEFT JOIN (
SELECT AE3.IDNo, SUM(ISNULL(AE3.Debit,0)) AS Debit, SUM(ISNULL(AE3.Credit,0)) AS Credit,
ABS(SUM(ISNULL(AE3.Debit,0))-SUM(ISNULL(AE3.Credit,0))) AS Balance
FROM AccountingEntries AE3 WITH (NOLOCK)
WHERE AE3.BookName NOT IN ('BFSL')
AND AE3.GLAccount = '1.03.01' AND ISNULL(AE3.TC,'') = 'LAC'
AND ((Datepart(MM,AE3.DateEntry)=Datepart(MM,#Date))
AND Datepart(YEAR,AE3.DateEntry)=Datepart(YEAR,#Date))
GROUP BY AE3.IDNo
) RL ON RL.IDNo = Loans.LoanID
Result set:
IDNo Debit Credit Balance
Is there a way to return a static result set whenever a derive table is empty by using ##ROWCOUNT?
like this:
IDNo Debit Credit Balance
EMP12 0 0 0
Thankss.
Here's one way to do what you want:
WITH MyQuery As
(
-- This is your original query
-- This returns no rows
SELECT 'I have no rows' As OriginalQuery WHERE 0=1
)
-- Select from your query
SELECT * FROM MyQuery
UNION ALL
-- If there's nothing in your query, UNION ALL this part
SELECT 'I only appear when there are no rows' WHERE NOT EXISTS (SELECT * FROM MyQuery)

SQL Query Get Last record Group by multiple fields

Hi I have a table with following fields:
ALERTID POLY_CODE ALERT_DATETIME ALERT_TYPE
I need to query above table for records in the last 24 hour.
Then group by POLY_CODE and ALERT_TYPE and get the latest Alert_Level value ordered by ALERT_DATETIME
I can get up to this, but I need the AlertID of the resulting records.
Any suggestions what would be an efficient way of getting this ?
I have created an SQL in SQL Server. See below
SELECT POLY_CODE, ALERT_TYPE, X.ALERT_LEVEL AS LAST_ALERT_LEVEL
FROM
(SELECT * FROM TableA where ALERT_DATETIME >= GETDATE() -1) T1
OUTER APPLY (SELECT TOP 1 [ALERT_LEVEL]
FROM (SELECT * FROM TableA where ALERT_DATETIME >= GETDATE() -1) T2
WHERE T2.POLY_CODE = T1.POLY_CODE AND
T2.ALERT_TYPE = T1.ALERT_TYPE ORDER BY T2.[ALERT_DATETIME] DESC) X
GROUP BY POLY_CODE, ALERT_TYPE, X.[ALERT_LEVEL]
POLY_CODE ALERT_TYPE ALERT_LEVEL
04575 Elec 2
04737 Gas 3
06239 Elec 2
06552 Elec 2
06578 Elec 2
10320 Elec 2
select top 1 with ties *
from TableA
where ALERT_DATETIME >= GETDATE() -1
order by row_number() over (partition by POLY_CODE,ALERT_TYPE order by [ALERT_DATETIME] DESC)
The way this works is that for each group of POLY_CODE,ALERT_TYPE get their own row_number() starting from the most recent alert_datetime. Then, the with ties clause ensures that all rows(= all groups) with the row_number value of 1 get returned.
One way of doing it is creating a cte with the grouping that calculates the latesdatetime for each and then crosses it with the table to get the results. Just keep in mind that if there are more than one record with the same combination of poly_code, alert_type, alert_level and datetime they will all show.
WITH list AS (
SELECT ta.poly_code,ta.alert_type,MAX(ta.alert_datetime) AS LatestDatetime,
ta.alert_level
FROM dbo.TableA AS ta
WHERE ta.alert_datetime >= DATEADD(DAY,-1,GETDATE())
GROUP BY ta.poly_code, ta.alert_type,ta.alert_level
)
SELECT ta.*
FROM list AS l
INNER JOIN dbo.TableA AS ta ON ta.alert_level = l.alert_level AND ta.alert_type = l.alert_type AND ta.poly_code = l.poly_code AND ta.alert_datetime = l.LatestDatetime

SQL Union Count to Sum Data

I have a bit of a complex query .... I need to do an update statement on the summation of two union-ed SQL queries (problem is the data in the queries isn't numeric so i'm counting rows instead of summing values) but I then need to sum those rows.
UPDATE #LT_Actuals_TEMP
SET pCount = h.countPerfs
FROM (
select count(distinct c.perf_description) as countPerfs, b.program, b.Prog_id
from #LT_Actuals_TEMP TableP
where a.Performances = 'Y' and a.current_inactive = 0
group by b.Program, b.Prog_id
union
select distinct count(p.perf_code) as countPerfs, x.value, b.Prog_id
from T_PERF p
where x.content_type = 23
group by x.value, b.Prog_id
) h where h.Prog_id = #LT_Actuals_TEMP.program_id
the first query data comes back as such
countPerfs program Prog_id
7 Name 31
and second query comes back as
countPerfs program Prog_id
1 Name 31
what I need pCount to be set to at the end of the day is 8
Expected results
when I do select * from #LT_Actuals_TEMP
I see the value
8 for the Program Name, Id 31
You can solve it by adding another level in the from part where you sum up the data returned from the union.
Your query seems to be missing some source tables (as there are aliases used that don't point to anything) so I guess you're removed some parts, but in general it should look something like this:
UPDATE #LT_Actuals_TEMP
SET pCount = h.sum_of_countperfs
FROM (
select program, prog_id, sum(countPerfs) as sum_of_countperfs
from (
select count(distinct c.perf_description) as countPerfs, b.program, b.Prog_id
from #LT_Actuals_TEMP TableP
where a.Performances = 'Y' and a.current_inactive = 0
group by b.Program, b.Prog_id
union all
select distinct count(p.perf_code) as countPerfs, x.value, b.Prog_id
from T_PERF p
where x.content_type = 23
group by x.value, b.Prog_id
) as sub_q group by program, prog_id
) h where h.Prog_id = #LT_Actuals_TEMP.program_id
Also, you probably want to use union all so that duplicates are not removed.

Select 1 of 2 similar records where does not

So I have a table called 'Requests' which stores requests for holidays. I want to try extract certain records from the table (joined with others) with the parameter of the clocknumber. But, if there are two records with the same HolidayID and the last (top 1 desc) is of a certain value - we dont include that in the select!
Request Table [shortened down version of it];
http://i.stack.imgur.com/YY1Gk.png
The stored procedure im using is passed a parameter for the username and joins three other tables,
a 'Holidays' table (Stores information on the holiday from, to etc)
a 'Users' table (contains usernames etc)
a 'RequestType' table (contains the types of requests)
From the image of the table, If you imagine all of those requests belong to the same user, I would want to extract only the records with a requesttype of 1. (the requesttype 1 is holiday request and 2 is holiday cancel). But, if there is a second record with the same holidayID and a requesttype of 2, it does not include that.
So running the query, I would want to only get records with the ID 1 and 2, because the last 2 have the same Holiday ID, and the last of the 2 is with a requesttype to cancel the holiday.
Here is my attempted query;
SELECT Holidays.ID, EmployeeClockNumber, Employees.Name AS EmployeeName, HolidayStart, HolidayEnd, HalfDay, AMPM
FROM Holidays
INNER JOIN Employees ON Employees.ClockNumber = Holidays.EmployeeClockNumber
INNER JOIN Requests ON Requests.HolidayID = Holidays.ID
WHERE EmployeeClockNumber = #ClockNo
AND Requests.Accepted = 1
AND RequestTypeID = (SELECT TOP 1 Requests.ID
FROM Requests
INNER JOIN Holidays ON Holidays.ID = Requests.HolidayID
WHERE Requests.RequestTypeID = (SELECT ID FROM RequestType WHERE RequestType = 'Holiday Request')
AND Holidays.EmployeeClockNumber = #ClockNo
ORDER BY Requests.ID DESC)
ORDER BY ID DESC
Could someone point me in the right direction? Thank you
edit: ive got it working myself!
SELECT Holidays.ID, Holidays.EmployeeClockNumber, Employees.Name AS EmployeeName, Holidays.HolidayStart, Holidays.HolidayEnd, Holidays.HalfDay, Holidays.AMPM
FROM Requests
INNER JOIN Holidays ON Holidays.ID = Requests.HolidayID
INNER JOIN Employees ON Employees.ClockNumber = Holidays.EmployeeClockNumber
WHERE Holidays.EmployeeClockNumber = #ClockNo
AND Requests.Accepted = 1
AND Requests.HolidayID NOT IN (SELECT TOP 1 HolidayID
FROM Requests AS R1
WHERE R1.RequestTypeID <> (SELECT ID FROM RequestType WHERE RequestType = 'Holiday Request')
AND R1.HolidayID = Requests.HolidayID
ORDER BY R1.ID DESC)
SELECT * FROM TAB WHERE requestTypeID = 1
AND holidayID not in (SELECT HolidayID from TAB WHERE requestTypeID = 2)
I would use a partition on the select and then filter on that.
So something like
DECLARE #mtable TABLE (
ID INT
,RequestTypeId INT
,HolidayId INT
,Accepted NVARCHAR(50)
)
INSERT #mtable VALUES (1,1,1,'True')
INSERT #mtable VALUES (2,1,2,'True')
INSERT #mtable VALUES (3,1,3,'True')
INSERT #mtable VALUES (4,2,3,'True')
SELECT * FROM (
SELECT MAX(RequestTypeId) OVER (PARTITION BY HolidayID) AS MaxType
,Id
FROM #mtable
) q
WHERE q.MaxType <> 2

Getting the sum of two select count statements

I've got two select queries I need to combine into one result.
/* Count of all classes students have passed */
/* A */
SELECT COUNT(TECH_ID) as Number1, ct.SUBJ, ct.COU_NBR
FROM [ISRS].[ST_COU] st
JOIN [ISRS].[CT_COU_SQL] ct
ON st.COU_ID = ct.COU_ID
WHERE GRADE = 'A' OR Grade = 'B' or Grade = 'C'
GROUP BY ct.SUBJ, ct.COU_NBR
/* Total Count of all students who needed to take a course */
/* B */
SELECT COUNT(TECH_ID) as Number2, ec.SUBJ, ec.COU_NBR
FROM [dbo].[ST_MAJOR_COMMENT] st JOIN [dbo].[Emphasis_Class] ec
ON st.MAJOR = ec.Emphasis
GROUP BY ec.SUBJ, ec.COU_NBR
I need SUBJ, COU_NBR, sum(B - A)
you can have your sql queries in the ctes and then do a join and group by
with cte1
as
(
first query
)
, cte2
as
(
second query
)
select cte1.subj, cte1.cou_nbr, sum(cte2.number2 - cte1.number1) as difference
from cte1
join cte2
on cte1.subj = cte2.subj
and cte1.cou_nbr = cte2.cou_nbr
group by cte1.subj, cte1.cou_nbr
Use union:
select sum(Number1) from (
SELECT COUNT(TECH_ID) as Number1
-- onit all other columns from select then rest of query 1
UNION
-- just the count column selected then rest of query 2
) x
This syntax will work with most databases.

Resources