Joined tables - how to aggregate problem (sum)? - sql-server

I have two tables joined like this:
SELECT count(DISTINCT T1.ContractNumber) AS nr_of_contracts,
count(T3.DateofInstallmentPayment) AS nr_of_paid_installents,
count(T3.DateofDueInstallment) AS nr_of_installments,
sum(T1.DisbursementAmount) AS disbursed_amount
FROM q.T1
LEFT JOIN q.T3
ON T1.ContractNumber=T3.ContractNumber
WHERE DateOfDisbursement BETWEEN '2019-12-01' AND '2019-12-31'
AND T3.DateofDueInstallment < GETDATE()
where T1 table contains data about clients (per contract number) and T3 about their payment schedules (per every instalment).
What I want is to have paid off amount (disbursement amount) of contracts from table T1 (aggregated by contract number) and not by every instalment. When I tried to select just sum(T1.Disbursement amount) then I receive sum but for all instalment which is incorrect.
T1:
Contract Number
DisbursementDate
Disbursement Amount
1
2019-12-01
1000
2
2019-12-01
2000
3
2019-12-01
3000
T3:
Contract Number
DateofDueInstallment
DateofInstallmentPayment
1
2020-01-01
2020-01-01
1
2020-02-01
2020-02-06
1
2020-03-01
2020-04-01
What I get after joining two tables for Contract Number = 1 is sum(DisbursementAmount) = 3000.
Contract Number
sum(DisbursementAmount)
1
3000
What I want after joining two tables for Contract Number = 1 is sum(DisbursementAmount) = 1000.
Contract Number
sum(DisbursementAmount)
1
1000

Something like this,not tested - a subquery with a different aggregation column
SELECT T1.product, T1.NrOfInstallment, count(DISTINCT T1.ContractNumber),
SELECT paid_amound FROM(SELECT ContractNumber, sum(tt.DisbursementAmount + (tt.ContractNumber*0.01))
- sum(tt.ContractNumber*0.01) as paid_amount
FROM abc.T1 as tt WHERE tt.ContractNumber = T1.ContractNumber GROUP BY ContractNumber) AS t)
FROM abc.T1
LEFT JOIN bde.T3
ON T1.ContractNumber=T3.ContractNumber
GROUP BY T1.product, T1.NrOfInstallment

Related

Joining multiple tables and applying aggegate giving wrong result

I have a business case where when a CountryId is passed to my proc, I need to get all the Regions where the Business is set up in that country, All the Active Sales Employees working in that Region, Total sales done by the current active sales employees in that region.
My Region table look like below.
RegionId | Name | CountryId
100 A 1
101 B 4
103 C 1
SalesEmployee Table
Id | EmployeeId | RegionId
1 250 100
2 255 101
3 289 101
Employee Table
EmployeeId | Active
250 1
255 1
289 0
314 1
Sales table
SaleId | EmployeeId| RegionId | Sale
1 100 2 3500
2 101 4 2000
3 100 2 1500
My below query is giving me the correct TotalSales value but the TotalUsers count doesn't match.
Select R.[RegionId], COUNT(SE.[UserId]) AS TotalUsers, SUM(S.[Sales]) AS TotalSales
FROM dbo.[Region] R
INNER JOIN [SalesEmployee] SE
ON R.[RegionId] = SE.[RegionId]
INNER JOIN dbo.[Employee] E
ON E.[EmployeeId] = SE.[EmployeeId]
LEFT JOIN dbo.[Sales] S
ON S.[EmployeeId] = E.[EmployeeId]
WHERE R.[CountryId] = 12 AND E.[Active] = 1
GROUP BY R.[RegionId]
For Ex RegionId 100 has only 7 Active sales employees currently working but the result gives me 89, in my Employee table there can be many more users but few of them can be inactive and few of them may be working in another department, to make sure that the employee is sales employee the employee needs to be present in SalesEmployee table and to check if the Employee is Active I need to check in Employee table.
The problem is 1 single user can have multiple entries on his name in sales table, so when i am joining with Sales table which has multiple entries on a single user then the TotalEmployees count is going up.
So its actually a easy small fix.
Select R.[RegionId], COUNT(DISTINCT(SE.[UserId])) AS TotalUsers, SUM(S.[Sales]) AS TotalSales
FROM dbo.[Region] R
INNER JOIN [SalesEmployee] SE
ON R.[RegionId] = SE.[RegionId]
INNER JOIN dbo.[Employee] E
ON E.[EmployeeId] = SE.[EmployeeId]
LEFT JOIN dbo.[Sales] S
ON S.[EmployeeId] = E.[EmployeeId]
WHERE R.[CountryId] = 12 AND E.[Active] = 1
GROUP BY R.[RegionId]
This small change will give you what you want.
Changing COUNT(SE.[UserId]) to COUNT(DISTINCT(SE.[UserId])) is all you need.

Sql Server - Get SUM() of values for only Active Users

I have a requirement where i need to get Total Active Employees and Total Sales by RegionId
My query result should be like below.
RegionId | TotalEmployees | TotalSales | Average
1 10 100 10
2 3 15 5
My front end application will pass all the RegionIds as a single string separated by a comma, my query parameter is of type VARCHAR() and the Input paramter will look like '1,2,3,4,7,14,26' and there can be upto 20 Region Ids in a single string separated by a comma.
SELECT E.[RegionId] as RegionId
,COUNT(E.[EmployeeId) AS TotalEmployees
,(SELECT SUM([Sale])
FROM dbo.[Sales]
WHERE RegionId = R.[RegionId]
) AS TotalSales
,TotalSales/TotalEmployees AS Average
FROM dbo.[Employee]
JOIN [dbo].[ufn_StringSplit](#RegionIdCollection, ',') RegionId
ON E.RegionId = CAST(RegionId.[Data] AS Varchar(5000))
WHERE E.[Active] = 1
GROUP BY E.[RegionId]
My Employee table structures look alike below
EmployeeId | Name | RegionId | Active
100 Tom 2 1
101 Jim 4 0
103 Ben 2 1
Sales Table
SaleId | EmployeeId| RegionId | Sale
1 100 2 3500
2 101 4 2000
3 100 2 1500
Now my issue is when i am getting TotalSales the below query gets all the sales by RegionId, but i need to get All the sales done by only current Active employees in the Employee table
(SELECT SUM([Sale])
FROM dbo.[Sales]
WHERE RegionId = R.[RegionId]
) AS TotalSales
There is no reason to use a sub-select to find the sum of sales here, that will result in running that query for each and every row. You want to aproach this in a set based way which means you need to join and group appropriately:
with s as
(
select e.RegionId
,e.EmployeeId
,sum(s.Sale) as EmployeeSales
from dbo.ufn_StringSplit(#RegionIdCollection, ',') as r
join dbo.Employee as e
on r.RegionId = CAST(r.[Data] AS varchar(20)) -- Do you really need 5000 characters here?
left join dbo.Sales as s
on r.RegionId = s.RegionId
and e.EmployeeId = s.EmployeeId
where e.Active = 1
group by e.RegionId
,e.EmployeeId
)
select s.RegionId
,count(s.EmployeeId) as TotalEmployees
,sum(s.EmployeeSales) as TotalSales
,sum(s.EmployeeSales)/count(s.EmployeeId) as Average
from s
group by s.RegionId

Error on Group by method

I wrote a query to combine records in multiple tables. Tables named by Purchase Order, Purchase Order Item
[ Note: The column names are not original names, it just for a model data]
In purchase order table have the order details like this,
id date vendorid totalitems totalqty grossamnt netamnt taxamt
----------------------------------------------------------------------------
1 03/10/17 00001 2 6 12000 13000 1000
Purchase Order Item table have the order details like this,
poid id productcode qty rate tax(%) taxamnt total
--------------------------------------------------------
1 1 12001 3 6000 2.5 500 6500
2 1 12000 3 6000 2.5 500 6500
My Query is,
select po.POID,po.SupplierId,po.TotalItems from
PurchaseOrder po, PurchaseOrderItem poi where po.POID=poi.POID group by
po.POID, po.SupplierId,po.TotalItems
Query returns,
id vendorid totalitems
--------------------------
1 00001 2
1 00001 2
Expected Output is,
id vendorid totalitems
------------------------
1 00001 2
You are using an outdated join method, have a read here:
ANSI vs. non-ANSI SQL JOIN syntax
You are also joining to another table, but never use it:
select po.POID,po.SupplierId,po.TotalItems
from PurchaseOrder po, PurchaseOrderItem poi
where po.POID=poi.POID
group by po.POID, po.SupplierId,po.TotalItems
Can just be:
select po.POID,po.SupplierId,po.TotalItems
from PurchaseOrder po
group by po.POID, po.SupplierId,po.TotalItem
OR
select DISTINCT
po.POID,
po.SupplierId,
po.TotalItems
from PurchaseOrder po

How can i use sql query for the following

My data table sampletime in one column and sample value in another column contain data like follow
sampletime value
----------------------------
2016-03-02 08:31:14 1
2016-03-02 09:31:14 2
2016-03-02 12:31:14 3
2016-03-04 08:31:14 4
2016-03-04 09:31:14 5
2016-03-05 08:31:14 3
I need two minimum sample time in each day. How can I group?
Query
SELECT rn.sampletime AS stime
FROM rn_qos_data_0007 rn
INNER JOIN s_qos_data qos
ON qos.table_id = rn.table_id
AND qos.qos = 'QOS_CPU_USAGE'
AND Substring(qos.origin, 1, 4) = 'A0C3'
AND qos.host = '10.98.48.100'
WHERE rn.sampletime BETWEEN '2016/01/01' AND '2016/06/22'
GROUP BY rn.sampletime
You need ROW_NUMBER window function
Select * From
(
select row_number()over(partition by cast(sampletime as date) order by sampletime) RN,*
From ..
) A
Where RN <=2

Filter two table rows by using group by with join in SQL Server

I have two tables as Sales and SalesDocument.
Sales Table
RequestId(PrimaryKey) ReqType DateTime
--------- ------- --------
1 Buy 22/10/2015
2 Buy 03/11/2015
3 Sell 10/11/2015
4 Return 11/12/2015
6 Sell 11/12/2015
7 Buy 20/12/2015
Sales Document Table
RequestId(Ref.Key(FK)) ReqDocument ReqDocURL
--------- ----------- ---------
2 Doc1 Http://..Doc1.PDF
3 Doc2 Http://..Doc2.PDF
3 Doc3 Http://..Doc3.PDF
4 Doc1 Http://..Doc1.PDF
4 Doc2 Http://..Doc2.PDF
4 Doc3 Http://..Doc3.PDF
6 Doc2 Http://..Doc2.PDF
6 Doc3 Http://..Doc3.PDF
Now I need to select the records in both tables by using RequestId(as Ref.Key) and the condition are,
1)In 1st Table,Need to get distinct ReqType(FirstColumn:RequestType) and It's count(SecondColumn:RequestTypeCount) based between two date ranges.
2)In 2nd Table, Need to calculate total no.of requested documents(ThirdColumn:SumOfReqDocument) by using RequestType(RequestType is not in 2nd table, hence we need to map with 1st table(sales) by RequestId and get the sum of documents.
The output should be,
RequestType RequestTypeCount SumOfReqDocument
----------- ---------------- ----------------
Buy 3 1
Sell 2 4
Return 1 3
I tried some SQL query but it does not result the actual result. Please help me on this SQL query\Suggest me some other query.
My Query is,
SELECT ReqType as RequestType,count(ReqType) as RequestTypeCount,count(salesDoc.DocumentURL) as SumOfReqDocument FROM Sales sales inner join SalesDocument salesDoc on
sales.RequestId=salesDoc.RequestId where sales.EndDate >= '2015-10-22 10:34:09.000' AND sales.EndDate <= '2015-12-31 00:00:00.000'
group by sales.ReqType
You may try change the INNER JOIN to LEFT JOIN, and COUNT DISTINCT ReqestID for RequestTypeCount
SELECT ReqType as RequestType
,count(DISTINCT sales.RequestId) as RequestTypeCount
,count(salesDoc.ReqDocURL) as SumOfReqDocument
FROM Sales sales
LEFT JOIN SalesDocument salesDoc
ON sales.RequestId=salesDoc.RequestId
WHERE sales.EndDate >= '2015-10-21 10:34:09.000' AND sales.EndDate <= '2015-12-31 00:00:00.000'
group by sales.ReqType

Resources