加入表并获得COUNT

时间:2012-02-26 19:37:51

标签: sql sql-server sql-server-2008

我将总结我的架构和我需要的结果:

Table A(released and rejected):
day, specimenid, status,bunch of other unneeded fields....
1,AA123, released
1,AA132, released
2,BB234, rejected
3,BB444, released
3,AA444, rejected

Table B(pending):
day, specimenid, bunch of other unneeded columns
1, BB333
1, H234
2, C333
3, F333

我需要的结果:

day, count, status
1, 2, released
1, 2, pending
2, 1, rejected
2, 1, pending
3, 1, released
3, 1, rejected
3, 1, pending

换句话说,对于每一天,我需要获得每个状态的总计数。

我这样做:

select day, count(specimenid) from tableA where status='released', 'released'

union all

select day, count(specimenid) from tableA where status='rejected', 'rejected'

union all

select day, count(specimenid) from tableB, 'pending'

它现在正在运作,但我认为它可能有点草率。

这是我对此的完整怪物查询:

WITH cte(rejected) AS (SELECT DISTINCT [Specimen ID]
                                                 FROM         dbo.QuickLabDump
                                                 WHERE     (Outcome = 'REJECTED') AND ([Specimen ID] IS NOT NULL))

    SELECT     CONVERT(VARCHAR(8), a.[Date Entered], 1) AS [Full Date], DATEPART(yy, a.[Date Entered]) AS [Year Entered], LEFT(DATENAME(MONTH, a.[Date Entered]), 3) 
                            AS [Month Entered], DATEPART(dd, a.[Date Entered]) AS [Day Entered], CASE WHEN DATEPART(WEEKDAY, [DATE entered]) 
                            = 1 THEN 'Sun' WHEN DATEPART(WEEKDAY, [DATE entered]) = 2 THEN 'Mon' WHEN DATEPART(WEEKDAY, [DATE entered]) 
                            = 3 THEN 'Tus' WHEN DATEPART(WEEKDAY, [DATE entered]) = 4 THEN 'Wed' WHEN DATEPART(WEEKDAY, [DATE entered]) 
                            = 5 THEN 'Thu' WHEN DATEPART(WEEKDAY, [DATE entered]) = 6 THEN 'Fri' WHEN DATEPART(WEEKDAY, [DATE entered]) = 7 THEN 'Sat' END AS DOW, 
                            CONVERT(VARCHAR(8), DATEADD(D, - (1 * DATEPART(dw, a.[Date Entered])) + 6, a.[Date Entered]), 1) AS [Week Ending], COUNT(DISTINCT a.[Specimen ID]) 
                            AS CountAccns, c.SALESREP AS [Sales Rep], c.NPI AS MLNPI, e.NPIb AS IMSNPI, e.SpecialtyPrimaryCodeb AS [IMS Specialty Primary Code],
                            sm1.specialtydesc as [Specialty Primary Description],
                            e.SpecialtySecondaryCodeb AS [IMS Specialty Secondary Code], 
                            sm2.specialtydesc as [Specialty Secondary Description],                            
                            e.SpecialtyTertiaryCodeb AS [IMS Specialty Tertiary Code], 
                            sm3.specialtydesc as [Specialty Tertiary Description],
                            e.ProfessionalID1b AS [IMS Professional ID 1], a.[Requesting Physician] AS Physician, a.[Practice Code], b.[MLIS Practice ID] AS [MLIS Code], a.[Practice Name], 
                            c.DATEESTABLISHED AS [Date Established], c.PRACTICEADDRESS1 AS Address, c.PRACTICEADDRESS2 AS Address2, c.PRACTICECITY AS City, 
                            c.PRACTICESTATE AS State, d.[MLIS Status] AS Status, MAX(a.[Order Count]) AS [order count],
                            'Released' as [Release Status]
     FROM         dbo.QuickLabDump AS a LEFT OUTER JOIN
                            dbo.qlmlismapping AS b ON b.[Quicklab ID] = a.[Practice Code] LEFT OUTER JOIN
                            dbo.PracticeandPhysician AS c ON a.[Requesting Physician] = c.DOCTORFIRSTNAME + ' ' + c.DOCTORLASTNAME AND 
                            a.[Practice Code] = c.PRACTICECODE LEFT OUTER JOIN
                            dbo.IMSData AS e ON c.NPI = e.NPIb LEFT OUTER JOIN
                            dbo.QLMLISInfo AS d ON b.[MLIS Practice ID] = d.[MLIS Practice ID]
                            left outer JOIN
                                dbo.SpecialtyMapping sm1 ON e.SpecialtyPrimaryCodeb = sm1.specialtyabbrev
                            left outer JOIN
                                dbo.SpecialtyMapping sm2 ON e.SpecialtySecondaryCodeb = sm2.specialtyabbrev
                            left outer JOIN
                                dbo.SpecialtyMapping sm3 ON e.SpecialtyTertiaryCodeb = sm3.specialtyabbrev
     WHERE     (a.[Date Entered] > '20110101') AND (NOT EXISTS
                                (SELECT     1 AS Expr1
                                  FROM          cte AS cte_1
                                  WHERE      (rejected = a.[Specimen ID]))) AND (NOT EXISTS
                                (SELECT     1 AS Expr1
                                  FROM          dbo.PendingSpecimens
                                  WHERE      ([Specimen ID] = a.[Specimen ID])))
     GROUP BY a.[Date Entered], c.SALESREP, c.NPI, e.NPIb, e.SpecialtyPrimaryCodeb, e.SpecialtySecondaryCodeb, e.SpecialtyTertiaryCodeb, e.ProfessionalID1b, 
                            a.[Requesting Physician], a.[Practice Code], b.[MLIS Practice ID], a.[Practice Name], c.DATEESTABLISHED, c.PRACTICEADDRESS1, c.PRACTICEADDRESS2, 
                            c.PRACTICECITY, c.PRACTICESTATE, d.[MLIS Status],sm1.specialtydesc,sm2.specialtydesc,sm3.specialtydesc


                            union all

                            select 
                                CONVERT(VARCHAR(8), a.[Date Entered], 1) AS [Full Date], 
                                DATEPART(yy, a.[Date Entered]) AS [Year Entered], 
                                LEFT(DATENAME(MONTH, a.[Date Entered]), 3) AS [Month Entered], 
                                DATEPART(dd, a.[Date Entered]) AS [Day Entered], 
                                CASE WHEN DATEPART(WEEKDAY, [DATE entered]) 
                                = 1 THEN 'Sun' WHEN DATEPART(WEEKDAY, [DATE entered]) = 2 THEN 'Mon' WHEN DATEPART(WEEKDAY, [DATE entered]) 
                                = 3 THEN 'Tus' WHEN DATEPART(WEEKDAY, [DATE entered]) = 4 THEN 'Wed' WHEN DATEPART(WEEKDAY, [DATE entered]) 
                                = 5 THEN 'Thu' WHEN DATEPART(WEEKDAY, [DATE entered]) = 6 THEN 'Fri' WHEN DATEPART(WEEKDAY, [DATE entered]) = 7 THEN 'Sat' END AS DOW, 
                                CONVERT(VARCHAR(8), DATEADD(D, - (1 * DATEPART(dw, a.[Date Entered])) + 6, a.[Date Entered]), 1) AS [Week Ending], 
                                COUNT(DISTINCT a.[Specimen ID]) AS CountAccns, 
                                null AS [Sales Rep], 
                                null AS MLNPI, 
                                null AS IMSNPI, 
                                null AS [IMS Specialty Primary Code],
                                null as [Specialty Primary Description],
                                null AS [IMS Specialty Secondary Code], 
                                null as [Specialty Secondary Description],  
                                null AS [IMS Specialty Tertiary Code], 
                                null as [Specialty Tertiary Description],
                                null AS [IMS Professional ID 1], 
                                null as Physician, 
                                SUBSTRING(agency,1,charindex(' - ',agency,1)-1) as [Practice Code], 
                                b.[MLIS Practice ID] AS [MLIS Code], 
                                SUBSTRING(agency,charindex(' - ',agency,1)+3,len(agency)) as [Practice Name], 
                                c.DATEESTABLISHED AS [Date Established], 
                                c.PRACTICEADDRESS1 AS Address, 
                                c.PRACTICEADDRESS2 AS Address2, 
                                c.PRACTICECITY AS City, 
                                c.PRACTICESTATE AS State, 
                                d.[MLIS Status] AS Status, 
                                null AS [order count],
                                'Pending' as [Release Status]
   from dbo.pendingspecimens AS a LEFT OUTER JOIN
                            dbo.qlmlismapping AS b ON b.[Quicklab ID] = SUBSTRING(agency,1,charindex(' - ',agency,1))
                             LEFT OUTER JOIN
                            dbo.PracticeandPhysician AS c ON  SUBSTRING(agency,1,charindex(' - ',agency,1)) = c.PRACTICECODE LEFT OUTER JOIN
                            dbo.IMSData AS e ON c.NPI = e.NPIb LEFT OUTER JOIN
                            dbo.QLMLISInfo AS d ON b.[MLIS Practice ID] = d.[MLIS Practice ID]
                         WHERE     (a.[Date Entered] > '20110101') 

                           group by  agency,a.[Date Entered], c.SALESREP, c.NPI, e.NPIb, e.SpecialtyPrimaryCodeb, e.SpecialtySecondaryCodeb, e.SpecialtyTertiaryCodeb, e.ProfessionalID1b, 
                             b.[MLIS Practice ID], c.DATEESTABLISHED, c.PRACTICEADDRESS1, c.PRACTICEADDRESS2, 
                            c.PRACTICECITY, c.PRACTICESTATE, d.[MLIS Status]

                            union all

                            SELECT     CONVERT(VARCHAR(8), a.[Date Entered], 1) AS [Full Date], DATEPART(yy, a.[Date Entered]) AS [Year Entered], LEFT(DATENAME(MONTH, a.[Date Entered]), 3) 
                            AS [Month Entered], DATEPART(dd, a.[Date Entered]) AS [Day Entered], CASE WHEN DATEPART(WEEKDAY, [DATE entered]) 
                            = 1 THEN 'Sun' WHEN DATEPART(WEEKDAY, [DATE entered]) = 2 THEN 'Mon' WHEN DATEPART(WEEKDAY, [DATE entered]) 
                            = 3 THEN 'Tus' WHEN DATEPART(WEEKDAY, [DATE entered]) = 4 THEN 'Wed' WHEN DATEPART(WEEKDAY, [DATE entered]) 
                            = 5 THEN 'Thu' WHEN DATEPART(WEEKDAY, [DATE entered]) = 6 THEN 'Fri' WHEN DATEPART(WEEKDAY, [DATE entered]) = 7 THEN 'Sat' END AS DOW, 
                            CONVERT(VARCHAR(8), DATEADD(D, - (1 * DATEPART(dw, a.[Date Entered])) + 6, a.[Date Entered]), 1) AS [Week Ending], COUNT(DISTINCT a.[Specimen ID]) 
                            AS CountAccns, c.SALESREP AS [Sales Rep], c.NPI AS MLNPI, e.NPIb AS IMSNPI, e.SpecialtyPrimaryCodeb AS [IMS Specialty Primary Code],
                            sm1.specialtydesc as [Specialty Primary Description],
                            e.SpecialtySecondaryCodeb AS [IMS Specialty Secondary Code], 
                            sm2.specialtydesc as [Specialty Secondary Description],                            
                            e.SpecialtyTertiaryCodeb AS [IMS Specialty Tertiary Code], 
                            sm3.specialtydesc as [Specialty Tertiary Description],
                            e.ProfessionalID1b AS [IMS Professional ID 1], a.[Requesting Physician] AS Physician, a.[Practice Code], b.[MLIS Practice ID] AS [MLIS Code], a.[Practice Name], 
                            c.DATEESTABLISHED AS [Date Established], c.PRACTICEADDRESS1 AS Address, c.PRACTICEADDRESS2 AS Address2, c.PRACTICECITY AS City, 
                            c.PRACTICESTATE AS State, d.[MLIS Status] AS Status, MAX(a.[Order Count]) AS [order count],
                            'Rejected' as [Release Status]
     FROM         dbo.QuickLabDump AS a LEFT OUTER JOIN
                            dbo.qlmlismapping AS b ON b.[Quicklab ID] = a.[Practice Code] LEFT OUTER JOIN
                            dbo.PracticeandPhysician AS c ON a.[Requesting Physician] = c.DOCTORFIRSTNAME + ' ' + c.DOCTORLASTNAME AND 
                            a.[Practice Code] = c.PRACTICECODE LEFT OUTER JOIN
                            dbo.IMSData AS e ON c.NPI = e.NPIb LEFT OUTER JOIN
                            dbo.QLMLISInfo AS d ON b.[MLIS Practice ID] = d.[MLIS Practice ID]
                            left outer JOIN
                                dbo.SpecialtyMapping sm1 ON e.SpecialtyPrimaryCodeb = sm1.specialtyabbrev
                            left outer JOIN
                                dbo.SpecialtyMapping sm2 ON e.SpecialtySecondaryCodeb = sm2.specialtyabbrev
                            left outer JOIN
                                dbo.SpecialtyMapping sm3 ON e.SpecialtyTertiaryCodeb = sm3.specialtyabbrev
                                join cte on cte.rejected=a.[Specimen ID]
     WHERE     (a.[Date Entered] > '20110101')
     GROUP BY a.[Date Entered], c.SALESREP, c.NPI, e.NPIb, e.SpecialtyPrimaryCodeb, e.SpecialtySecondaryCodeb, e.SpecialtyTertiaryCodeb, e.ProfessionalID1b, 
                            a.[Requesting Physician], a.[Practice Code], b.[MLIS Practice ID], a.[Practice Name], c.DATEESTABLISHED, c.PRACTICEADDRESS1, c.PRACTICEADDRESS2, 
                            c.PRACTICECITY, c.PRACTICESTATE, d.[MLIS Status],sm1.specialtydesc,sm2.specialtydesc,sm3.specialtydesc

我真的不认为我应该做UNION ALL,而是以更智能的方式构建查询。你能帮我简化查询,这样我就不需要做UNION ALLs了吗?

2 个答案:

答案 0 :(得分:3)

怎么样?

select day, count(*) as count, status from TableA
group by day, status
union
select day, count(*) as count, 'pending' from TableB
group by day

如果您在TableA中拥有超过这两个状​​态,则可以添加where子句来过滤它们。

我认为你不能逃离union。记录在不同的表中,您需要从两个表中获取它们。

它也是union而不是union all。后者将删除重复项,并将需要更多的执行。我们不需要因为我写的查询中没有重复...我不能保证你在问题中粘贴的大量内容:P

答案 1 :(得分:1)

我的想法是在一个简单的CTE中结合你的来源,然后有一个“怪物”查询:

; with cte as ( --union all for source rows without joins and clauses
    select * from A
    union all
    select *,'pending' from B
)
-- "monster" query without the union
select [day]
, [status]
, statusCount=COUNT(*)
from cte
group by [day], [status]
order by [day], [status]