Related
loan_no loan_amt contact date customer_id salesman_id
I have the following table. I need to somehow get the average of loan_no and the average of loan_amt for the people with more than one loan_no. I need to somehow plug in the avg and count functions.
I am seriously struggling with that. I was also thinking of a pivot function.
I would really appreciate it if someone can suggest a SQL code
My efforts so far:
select count (loan_no), tcustomer_id
from table
group by customer_id
having count (loan_no) > 1
Now I just do not know how to also include the avg function.
Not sure why do you need average Loan_no but you can still get it through -
select customer_id, avg(loan_no), avg(loan_amt)
from (select *, count(*) over(partition by customer_id) cnt
from table)
where cnt > 1
group by customer_id
You can use two levels of aggregation:
select avg(num_loans), sum(total) / sum(num_loans)
from (select customer_id, count(*) as num_loans, sum(loan_amt) as total
from table
group by customer_id
) t
where num_loans > 1;
I have a table as shown in this screenshot:
I want to group by the Employees to calculate AssetEarned, but with the following logic:
Sum the same dates, then
Average the different dates
The output expected is like the following picture.
Can this be achieved using a group by? I can use SUM, or AVG in the group by statement individually, but not at the same time. How to achieve this?
You can achieve this by using simple the SUM and Count functions in SQL
SELECT ID,NAME,(SUM(ASSET_EARNED)/CAST(COUNT(DISTINCT DATE) AS FLOAT)) AS ASSET_EARNED
FROM (
VALUES (1,1,'Bruce',5,'10-Jan'),(2,1,'Bruce',7,'10-Jan'),(3,1,'Bruce',6,'12-Jan'),
(4,2,'Clark',4,'11-Jan'),(5,2,'Clark',3,'12-Jan')
)S(KeyID,ID,NAME,ASSET_EARNED,DATE)
GROUP BY ID,NAME
Another option to avoid the DISTINCT inside Count function
SELECT A.ID,A.NAME,SUM(A.ASSET_EARNED)/CAST(COUNT(DATE) AS FLOAT) AS ASSET_EARNED
FROM(
SELECT ID,NAME,DATE,(SUM(ASSET_EARNED)) AS ASSET_EARNED
FROM (
VALUES (1,1,'Bruce',5,'10-Jan'),(2,1,'Bruce',7,'10-Jan'),(3,1,'Bruce',6,'12-Jan'),
(4,2,'Clark',4,'11-Jan'),(5,2,'Clark',3,'12-Jan')
)S(KeyID,ID,NAME,ASSET_EARNED,DATE)
GROUP BY ID,NAME,DATE) A
GROUP BY ID,NAME
You could use a subquery in which you SUM the values first before using AVG:
SELECT t.EmployeeID,
t.EmployeeName,
AVG(t.AssetEarned) AssetEarned
FROM
(
SELECT t.EmployeeID,
t.EmployeeName,
SUM(CONVERT(FLOAT, t.AssetEarned)) AssetEarned
FROM yourTable t
GROUP BY t.EmployeeID, t.EmployeeName, t.[Date]
) t
GROUP BY t.EmployeeID, t.EmployeeName
ORDER BY t.EmployeeID
You just need to use Count of Unique Dates and divide sum of asset into them.
SELECT
e.EmployeeId,e.EmployeeName,cast(SUM(e.AssetEarned) AS FLOAT)/Cast(COUNT(DISTINCT e.Date) AS FLOAT) AssetEarned
FROM Employee AS e
GROUP BY e.EmployeeId,e.EmployeeName
Trying to get an overall distinct count of the employees for a range of records which has a group by on it.
I've tried using the "over()" clause but couldn't get that to work. Best to explain using an example so please see my script below and wanted result below.
EDIT:
I should mention I'm hoping for a solution that does not use a sub-query based on my "sales_detail" table below because in my real example, the "sales_detail" table is a very complex sub-query.
Here's the result I want. Column "wanted_result" should be 9:
Sample script:
CREATE TEMPORARY TABLE [sales_detail] (
[employee] varchar(100),[customer] varchar(100),[startdate] varchar(100),[enddate] varchar(100),[saleday] int,[timeframe] varchar(100),[saleqty] numeric(18,4)
);
INSERT INTO [sales_detail]
([employee],[customer],[startdate],[enddate],[saleday],[timeframe],[saleqty])
VALUES
('Wendy','Chris','8/1/2019','8/12/2019','5','Afternoon','1'),
('Wendy','Chris','8/1/2019','8/12/2019','5','Morning','5'),
('Wendy','Chris','8/1/2019','8/12/2019','6','Morning','6'),
('Dexter','Chris','8/1/2019','8/12/2019','2','Mid','2.5'),
('Jennifer','Chris','8/1/2019','8/12/2019','4','Morning','2.75'),
('Lila','Chris','8/1/2019','8/12/2019','2','Morning','3.75'),
('Rita','Chris','8/1/2019','8/12/2019','2','Mid','1'),
('Tony','Chris','8/1/2019','8/12/2019','4','Mid','2'),
('Tony','Chris','8/1/2019','8/12/2019','1','Morning','6'),
('Mike','Chris','8/1/2019','8/12/2019','4','Mid','1.5'),
('Logan','Chris','8/1/2019','8/12/2019','3','Morning','6.25'),
('Blake','Chris','8/1/2019','8/12/2019','4','Afternoon','0.5')
;
SELECT
[timeframe],
SUM([saleqty]) AS [total_qty],
COUNT(DISTINCT [s].[employee]) AS [employee_count1],
SUM(COUNT(DISTINCT [s].[employee])) OVER() AS [employee_count2],
9 AS [wanted_result]
FROM (
SELECT
[employee],[customer],[startdate],[enddate],[saleday],[timeframe],[saleqty]
FROM
[sales_detail]
) AS [s]
GROUP BY
[timeframe]
;
If I understand correctly, you are simply looking for a COUNT(DISTINCT) for all employees in the table? I believe this query will return the results you are looking for:
SELECT
[timeframe],
SUM([saleqty]) AS [total_qty],
COUNT(DISTINCT [s].[employee]) AS [employee_count1],
(SELECT COUNT(DISTINCT [employee]) FROM [sales_detail]) AS [employee_count2],
9 AS [wanted_result]
FROM #sales_detail [s]
GROUP BY
[timeframe]
You can try this below option-
SELECT
[timeframe],
SUM([saleqty]) AS [total_qty],
COUNT(DISTINCT [s].[employee]) AS [employee_count1],
SUM(COUNT(DISTINCT [s].[employee])) OVER() AS [employee_count2],
[wanted_result]
-- select count form sub query
FROM (
SELECT
[employee],[customer],[startdate],[enddate],[saleday],[timeframe],[saleqty],
(select COUNT(DISTINCT [employee]) from [sales_detail]) AS [wanted_result]
--caculate the count with first sub query
FROM [sales_detail]
) AS [s]
GROUP BY
[timeframe],[wanted_result]
Use a trick where you only count each person on the first day they are seen:
select timeframe, sum(saleqty) as total_qty),
count(distinct employee) as employee_count1,
sum( (seqnum = 1)::int ) as employee_count2
9 as wanted_result
from (select sd.*,
row_number() over (partition by employee order by startdate) as seqnum
from sales_detail sd
) sd
group by timeframe;
Note: From the perspective of performance, your complex subquery is only evaluated once.
How can I find the sum of the lowest five points in the Point column
and group by ID
Table
The desired results should be;
Results
No idea where to start
Thanks
select a.ID, SUM(a.points) from(select ID , points,row_number() over
(partition by ID order by POINTS) as rownum_returned from your_table) a where
a.rownum_returned<6 group by a.ID;
Read about row_number() function here
If I've to do that I would solve it with a subquery.
In SQL server I will do subquery that retrieve the 5 lower point
Select Top 5 id, point from table
Order by point asc
Note: the keyword TOP that limit the result to the first 5
Note 2: order by point asc will order the result putting in top the lowest value
Now I use the query as subquery to complete the activity
Select id, sum (point) from
(Select top 5 id,point from table order by point asc) group by id
This should work
I have a table that stores the number of users who score in a particular range. I am trying to design a query that will show the total number of students who scored in that range. The table has repetitions since its a log table. here is there table
Here is my query
select id, min, max, count(Score)
from Scorelogs
I know I have to use "COUNT" in the query but I don't know how to group by the min and max.
You want to just group by the range:
select "min", "max", sum(score)
from data
group by "min", "max"
order by 1, 2;
Note that min and max are very poor names for columns, because they conflict with the built in functions that have the same names.
Use as , In this scenerio id is not generated.
select min,max, count(Score) from Scorelogs group by min,max
Or you can use
select ROW_NUMBER()
OVER (ORDER BY max) AS id, min,max, count(Score) from Scorelogs group by min,max
SELECT ROW_NUMBER() OVER(ORDER BY min,max) as id,
min,
max,
SUM(Score)
FROM Scorelogs
GROUP BY min,max
Fiddle Demo