-1

データソースとして動的レポートのクエリがあります。これまでの結果は次のとおりです。

ここに画像の説明を入力

に接続された 3 つのクエリがありますUNION。1 行目は、会社で蓄積されたすべてのデータです。行 2 は場所のすべてのデータで、行 3 は詳細データです。

それは木のようなものです。しかし、私の問題は、累積が正しくないことです (AnzahlMinuten)。このデータを動的レポートに表示する別の方法はありますか? この 3 つのクエリは非常に時間がかかる可能性があります。ライセンスが使用されている時間のエントリが複数あるため、RANK() 関数も使用します。

他に簡単な解決策がない場合、ユニオンを使用して接続されたクエリのどこに問題があるので、累積が正しくないのでしょうか?

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
4

1 に答える 1

1

主な問題は「distinct」の使用にあると思います。これはコーディングの問題ではありません。複数のグループ化レベルで個別を合計すると、サブグループの合計がトップ グループの合計よりも大きくなる場合があります。例えば:

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

グループ 1 の
合計 (個別値) = 6 グループ 2 の合計 (個別値) = 11
両方のグループの合計 (個別値) = 15

また、一般的に、単一のレコードセットで複数のグループ化レベルの問題を解決するためのより適切な方法を求めているようです。私は前職でこんなことをしていました。

SQLフィドル

アイデアは、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

次に、それを 3 つのレベルのデータに結合し、レベル 1、レベル 2、レベル 3 でグループ化します。それはずっときれいです。

于 2013-07-03T15:31:05.357 に答える