Reputation: 23
I have the following situation. I have a “Client” Table (Parent) and an “Opportunity” Table Child table. (See example below).
Client Table
| Id | Name
------------------
|1 | Client A
|2 | Client B
|3 | Client C
Opportunity Table
| Id | ClientId | Value
---------------------------------
| 10 | 1 | 1000
| 11 | 1 | 3000
| 12 | 2 | 1500
| 13 | 3 | 2000
I want to show sum of all Total of Opportunity Value (OppValue) on the client record.
Expected Output
| Id | Name | OppValue
-----------------------------
|1 | Client A | 4000
|2 | Client B | 1500
|3 | Client C | 2000
The business requirement is to filter on “OppValue” with the following criteria greater than, less than or null, etc but not by opportunity create date, etc. We are expecting each year users will be adding 500 clients and 45000 new opportunities. Based on the above I can think of three options
Which of the solution in your opinion will work best in terms of User experience (speed) and maintenance? In case there is a better suggestion please let me know.
Many thanks in advance.
Upvotes: 0
Views: 108
Reputation: 1270401
Start with a view:
create view client_opp as (
select c.*, o.oppvalue
from client c outer apply
(select sum(oppvalue) as oppvalue
from opportunities o
where o.clientId = c.clientId
) o;
Be sure you have an index on opportunities(clientId, oppvalue)
-- or at least on opportunities(clientId)
. Note that this uses apply
quite specifically so the view should work well even when used in a query with additional filtering.
If this works performance-wise, then you are done. Other methods using triggers and UDFs require a bit more maintenance in the database. You can definitely use them, but I would recommend waiting to see if this meets your performance needs.
Upvotes: 1
Reputation: 5653
Try the following query using inner join
and sum()
function. To know more about inner join you can follow this link. You can learn in detail about the Aggregate Functions (Transact-SQL) here.
Create table Client
(Id int, Name Varchar(20))
insert into Client values
(1, 'Client A'),
(2, 'Client B'),
(3, 'Client C')
create table Opportunity
(Id int, ClientId int, Value int)
insert into Opportunity values
(10, 1, 1000 ),
(11, 1, 3000 ),
(12, 2, 1500 ),
(13, 3, 2000 )
Select Client.Id, Client.Name, sum(Value) as Value
from Client
inner join Opportunity on Client.Id = Opportunity.ClientId
group by Client.Id, Client.Name
Output
Id Name Value
----------------------
1 Client A 4000
2 Client B 1500
3 Client C 2000
To create a view you can use the following create view example.
Syntax:
Create View <ViewName>
as
<View Query>
Example:
create view MyView
as
Select Client.Id, Client.Name, sum(Value) as Value
from Client
inner join Opportunity on Client.Id = Opportunity.ClientId
group by Client.Id, Client.Name
Selecting the result from a view as created above.
select * from MyView
Upvotes: 0
Reputation: 50173
You can use apply
:
create view client_view as
select c.*, ot.OppValue
from ClientTable c cross apply
( select sum(value) as OppValue
from OpportunityTable ot
where ot.ClientId = c.ClientId
) ot;
Upvotes: 0