树/组UNION SQL查询报告

时间:2013-07-03 13:24:12

标签: sql sql-server union dynamic-reports

我有一个关于dynamicreport作为数据源的查询。 到目前为止的结果是:

enter image description here

有3个查询与UNION相关联。第1行为公司累计的所有数据。第2行所有数据为位置,第3行为详细数据。

它就像一棵树。但我的问题是,积累是不正确的(AnzahlMinuten)。是否有其他方法可以在动态报表中显示此数据。这3个查询可能非常紧张。我也使用RANK()函数,因为我在使用许可证时有多个条目。

如果没有其他更简单的解决方案,我在使用union的连接查询中的错误在哪里,那么积累是不正确的?

SELECT Gesellschaftsname,Standortname,Lizenzname,Abteilungsname,Kostenstelle,    
COUNT(DISTINCT username) AS AnzahlUser,
SUM(DISTINCT RuntimeMinute) AS AnzahlMinuten,

1 FROM  (SELECT * FROM(SELECT DISTINCT Standortname,
                        DATEPART(YEAR,PK_Date) AS Jahr,
                        DATEPART(month,PK_Date) AS Monat,
                        Lizenzname,COUNT(DISTINCT username) AS AnzUser,
                        SUM(DISTINCT DATEDIFF(minute,starttime ,pk_date))  AS RuntimeMinute,
                        starttime,
                        username,
                        pk_date,
                        Abteilungsname,
                        Gesellschaftsname,
                        Kostenstelle,
                        RANK() Over (PARTITION BY starttime ORDER BY pk_date DESC) As Rank 
                        FROM BenutzerLizenz,Benutzer,Abteilung,Lizenz,Standort,Gesellschaft,Kostenstelle
                        WHERE BenutzerLizenz.PK_ID_user=Benutzer.PK_ID_user AND BenutzerLizenz.PK_ID_lic=Lizenz.PK_ID_lic AND PK_ID_standort=FK_ID_standort AND  PK_ID_Abteilung = FK_ID_Abteilung AND PK_ID_Gesellschaft = FK_ID_Gesellschaft AND PK_ID_Kostenstelle = FK_ID_Kostenstelle AND
                        DATEPART(month,PK_Date) IN ('06','07') AND 
                        DATEPART(YEAR,PK_Date) = '2013' AND
                        Lizenzname IN ('DESIGNER','iman_nth') AND 
                        Standortname IN ('Unterlüß','Neuenburg') 
                        GROUP BY Standortname, Lizenzname, starttime, pk_date, username ,Abteilungsname, Kostenstelle, Gesellschaftsname) tmp 
                        WHERE Rank = 1)tmp2 GROUP BY Standortname,Lizenzname,Abteilungsname, Kostenstelle, Gesellschaftsname

UNION

SELECT Gesellschaftsname,'','','','',
COUNT(DISTINCT username) AS AnzahlUser,
SUM(DISTINCT RuntimeMinute) AS AnzahlMinuten,2
FROM  (SELECT * FROM(SELECT DISTINCT Gesellschaftsname,
                        DATEPART(YEAR,PK_Date) AS Jahr,
                        DATEPART(month,PK_Date) AS Monat,
                        COUNT(DISTINCT username) AS AnzUser,
                        SUM(DISTINCT DATEDIFF(minute,starttime ,pk_date))  AS RuntimeMinute,
                        starttime,
                        username,
                        pk_date,
                        RANK() Over (PARTITION BY starttime ORDER BY pk_date DESC) As Rank 
                        FROM BenutzerLizenz,Benutzer,Lizenz,Standort,Gesellschaft
                        WHERE BenutzerLizenz.PK_ID_user=Benutzer.PK_ID_user AND BenutzerLizenz.PK_ID_lic=Lizenz.PK_ID_lic AND  PK_ID_Gesellschaft = FK_ID_Gesellschaft AND
                        DATEPART(month,PK_Date) IN ('06','07') AND 
                        DATEPART(YEAR,PK_Date) = '2013' AND
                        Lizenzname IN ('DESIGNER','iman_nth') AND 
                        Standortname IN ('Unterlüß','Neuenburg') 
                        GROUP BY Gesellschaftsname,starttime, pk_date, username) tmp 
                        WHERE Rank = 1)tmp2 GROUP BY Gesellschaftsname

UNION

SELECT '',Standortname,'','','',
COUNT(DISTINCT username) AS AnzahlUser,
SUM(DISTINCT RuntimeMinute) AS AnzahlMinuten,3
FROM  (SELECT * FROM(SELECT DISTINCT Standortname,
                        DATEPART(YEAR,PK_Date) AS Jahr,
                        DATEPART(month,PK_Date) AS Monat,
                        COUNT(DISTINCT username) AS AnzUser,
                        SUM(DISTINCT DATEDIFF(minute,starttime ,pk_date))  AS RuntimeMinute,
                        starttime,
                        username,
                        pk_date,
                        RANK() Over (PARTITION BY starttime ORDER BY pk_date DESC) As Rank 
                        FROM BenutzerLizenz,Benutzer,Abteilung,Lizenz,Standort
                        WHERE BenutzerLizenz.PK_ID_user=Benutzer.PK_ID_user AND BenutzerLizenz.PK_ID_lic=Lizenz.PK_ID_lic AND PK_ID_standort=FK_ID_standort AND PK_ID_Abteilung = FK_ID_Abteilung AND
                        DATEPART(month,PK_Date) IN ('06','07') AND 
                        DATEPART(YEAR,PK_Date) = '2013' AND
                        Lizenzname IN ('DESIGNER','iman_nth') AND 
                        Standortname IN ('Unterlüß','Neuenburg') 
                        GROUP BY Standortname, starttime, pk_date, username) tmp 
                        WHERE Rank = 1)tmp2 GROUP BY Standortname
                        ORDER BY 2

1 个答案:

答案 0 :(得分:1)

我认为主要问题是使用“不同”。这不是编码问题。当在多个分组级别上求和时,子组的总数可能大于顶部组的总数。例如:

GroupId Value
1       1
1       2
1       3
2       2
2       4
2       5

第1组的总和(不同值)= 6
第2组的总和(不同值)= 11
两组的总和(不同值)= 15

此外,一般来说,这听起来像是在寻求一种更简洁的方法来解决单个记录集中多个分组级别的问题。我在之前的工作中做过类似的事情:

sql fiddle

我们的想法是,您首先在CTE中构建可能的组列表

Level1 Level2 Level3
A      NULL   NULL
A      AA     NULL
A      AB     NULL
A      AA     AAA
A      AA     AAB
A      AB     ABA
A      AB     ABB

然后将其加入三个级别的数据,并按Level1,Level2,Level3分组。它更清洁了。