2013-07-03 2 views
-1

У меня есть запрос для dynamicreport в качестве источника данных. результат до сих пор является:Дерево/группа UNION SQL-запрос для отчета

enter image description here

Есть 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 

ответ

1

Я думаю, что основная проблема заключается в использовании «отличных». Это не проблема кодирования. При суммировании, отличном от нескольких уровней группировки, итоговые суммы подгрупп могут быть больше, чем общая сумма верхней группы. Например:

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

сумма (определенное значение) на 1-й группе = 6
сумма (определенное значение) на 2-й группе = 11
сумма (определенное значение) на обеих групп = 15

Кроме того, в общем, похоже, вы просите более аккуратный способ решить эту проблему с несколькими уровнями группировки в одном наборе записей. Я сделал что-то вроде этого на предыдущем месте работы:

sql fiddle

Идея заключается в том, что вы строите список возможных групп первого в КТР, как

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

затем присоединиться, что ваших данных на три уровня и группу по Уровню 1, Уровень 2, Уровень 3. Это намного чище.

+0

Благодарим вас. Я могу следовать вашему примеру с отличным. В моем примере, который я редактировал, я старался не использовать отдельные, чтобы подытожить значения, но это не помогло мне, значения все еще ошибочны. Если нет решения, я должен попробовать ваш второй пример. – janor

+0

Я удалил все ключевые слова 'DISTINCT' во внешних SELECTS' SUM (RuntimeMinute) AS AnzahlMinuten, и, похоже, теперь работает. – janor

+0

Приятно слышать, Ян! –