Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
Blastrix
Posting Yak Master
208 Posts |
Posted - 2003-05-11 : 16:49:21
|
| Jeff or anyone else who might have an answer,I have a problem similar to the one I encountered in the last topic you helped me with, but for some reason the results being produced aren't as expected. I have a table with contracts and their statuses, I need to pull a report for a specified date range of the number of each status that occurred during that period, broken down by partner. I figured the cross join would give me what I wanted, except it either multiplies the Count() by 5(the number of possible statuses), and doesn't even show all statuses, or it gets the count of all records for the partner for each status, instead of the number of records per status, per partner. Below is a run down version of the query I'm using.Select C.PartnerName, CAS.ContractAcceptanceStatus, Count(C.ContractAcceptanceStatusID)From vwContracts C Cross Join tblContractAcceptanceStatuses CASGroup By C.PartnerName, CAS.ContractAcceptanceStatusOrder By C.PartnerNameIf I group by and use CAS.ContractAcceptanceStatus, then I get the number of records per partner for each status. If I group by and use C.ContractAcceptanceStatus, then I get the counts multiplied by 5, but not all statuses per partner.Thanks,SteveEdited by - blastrix on 05/11/2003 17:05:46 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2003-05-11 : 18:27:23
|
| Close ... you almost always need to use subqueries when using these techniques.Think of it in two pieces:Part 1: You want to return a row for EVERY partner, and for EVERY acceptance type:SELECT P.PartnerName, CAS.ContractAcceptanceStatusFROMPartners P (you do have this table, right?)CROSS JOINtblContractAcceptanceStatuses CAS (Replace the "Partners" table with either the master table of partners, or a subquery that returns 1 row per partner you wish to show on this report)Part 2: Totally seperate from SQL1, create a SQL statement that returns the numbers you want to show each partner/status combination. Make sure the "primary key" of this query is partner/status:Select C.PartnerName, C.ContractAcceptanceStatus, COUNT(*) as StatusCountFROMvwContracts CGROUP BY PartnerName, ContractAcceptanceStatus(you may need to edit the above based on your data, but I imagine it is something like that).Part 3: (Final Result)Now, just do a left outer join from part 1 to part 2:Select a.partnerName, a.ContractAcceptanceStatus isnull(b.StatusCount,0) as StatusCountFROM(Part 1) aLEFT OUTER JOIN(part 2) bON a.PartnerName = b.PartnerName ANDa.ContractAcceptanceStatus = b.ContractAcceptanceStatus----I hope this makes some sense and clears things up. You have to do it in steps. The CROSS JOIN is only for ensuring you have EVERY combination that you need. If you don't need a row for EVERY partner and for EVERY status, don't bother with it. It is just a way to guarantee you return a row for every combination (and allows you a chance to return 0's when there is no data).Same thing if you said: "Give me sales per month, per region, per product -- and show a 0 if there are no sales":Select A.Month, B.Region. C.Product, ISNULL(D.TotalSales,0) as TotalSalesFROMMonths ACROSS JOINRegions BCROSS JOINProducts CLEFT OUTER JOIN (SELECT month, region, product, sum(Sales) as TotalSales FROM Salesdata GROUP BY month, region, product) DonA.Month = d.Month ANDB.Region = d.Region ANDC.Product = d.ProductI call this the (A x B) -> C technique. You cross join A and B to make you you have all of the dimensions your query needs to return (regardless of actual data), and then a LEFT OUTER JOIN to C which is the actual data properly summarized. Trust me on this: if you can master this technique, you will be the ultimate SQL query writer (especially for writing reports). Things that aren't normally possible to return (or very inefficient to return) become very straightfoward and make perfect logical sense when you apply this method. - JeffEdited by - jsmith8858 on 05/11/2003 18:30:13 |
 |
|
|
|
|
|
|
|