I need some help with forming basic SQL-VIEWs for a bunch of my tables. Here's a quick overview
- I've a ClaimDetail table and it has got some Lookup fields like StatusID, BrandID, SalespersonID, etc..
- As usual, the lookup fields map to master tables like MasterStatus, MasterBrand, ... {Structure: ID, Title}
- Also there're two other tables Comments and Files. A Claim can have multiple Comments and multiple Files.
- I need to display a Dashboard which will be a list of Claims. I need to display titles from the Master tables and count of the comments & files.
Now, I've two views of this Dashboard one is for users of type Customer which is limited to certain details and another one is a detailed view which is meant for Internal users. You can say that the Customer view is a sub-set of the Internal view.
I see two options -
- Opt#1: Create a single vw_Internal view and use it to fetch data for both the Users.
- Opt#2: I create a vw_Customer which has onlt those fields which are required for the Customer and then I create a 开发者_如何转开发vw_Internal which will be like: vw_Customer INNER JOIN Master tables. In short I'll extend the basic vw_Customer to include more fields.
Does option#2 make sense from speed and performance point of view? Opt#1 is simple but considering the huge number of records I want to make sure that the Customers don't have to wait a bit longer for those extra lookups which not are going to be included in their Dashboard.
Finally, is there a way for the last feature I mentioned? That is getting the count of Comments and Files which has a one-to-many relationship with the ClaimDetail table. I just need the count or atleast a boolean field which says whether a claim has any Comments or not (Same for Files) - if'll be false if the count = 0. I'm also concerned about the performane impact due to this feature.
Thanks in advance.
With regards to the view definitions, I'd build two views, and I'd make them separate--neither view would reference the other. This would allow you to optimize the queries independantly, and it avoids any problems you'd get with views layered on top of views; too many layers can make databases management, maintenance, and refactoring particularly challenging.
As for the data aggregation, common tactics include the following. Compare, contrast, test, and extrapolate to see what fits best in your environment:
Subqueries
SELECT mt.Id, st1.HowMany, st2.HowManyOther, <etc>
from MainTable mt
inner join (select Id, count(*) HowMany
from SubTable1
group by Id) st1
on st1.Id = mt.Id
inner join (select Id, count(*) HowMany
from SubTable2
group by Id) st2
on st2.Id = mt.Id
Fairly straightforward, though the subqueries might get kind of costly, even with proper indexing.
count(distinct xx)
SELECT mt.Id, count(distinct st1.UniqueKey) HowMany, count(distinct st2.UniqueKey) HowManyOther, <etc>
from MainTable mt
inner join SubTable1 st1
on st1.Id = mt.Id
inner join SubTable2
on st2.Id = mt.Id
This requires a single unique column in the "subtables", and gets messy if you have to deal with outer joins or NULLs.
Added
First, replacing the inner joins with (left) outer joins in either of the above queries will produce 0+ counts from the subtables, so long as you make sure the count is being done on the “right” table (because NULLs don’t get tallied). To figure out which performs best on your environment, you’d have to write and test both queries. I’d guess the second, since the first requires table scans on the tables of the subqueries while the second performs joins and so may optimize better, but the SQL query optimizer is smarter than me (because it knows your indexes and has distribution histograms of your data) so you want to see what it comes up with.
With regards to “layered views”, if I’m following the logic right, I’d recommend building the Internal view as the complex/comprehensive query (all the joins, all the relevant columns), and then build the Customer view that’s hopefully as simple as
SELECT <customerOnlyColumns>
from vw_Internal
精彩评论