Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi SQL "umbauen" (https://www.delphipraxis.net/109525-sql-umbauen.html)

Salomon 3. Mär 2008 10:30

Re: SQL "umbauen"
 
Hey,
das ich über die Joins eine große Datenmenge "baue" war mir klar. Das die Spalten auf NULL stehen wenn sie nicht passen war mir nicht so bewust. Ohne die NULL Prüfung konnte ich dann gar nicht an die Daten kommen.

Salomon 29. Apr 2008 08:54

Re: SQL "umbauen"
 
Hi all,
ich muss den Thread noch einmal reaktivieren. Mir ist aufgefallen, das in der Ergebnismenge nicht alle Teams aus der TeamTabelle auftauchen. Drei fehlen. Allerdings sehe ich nicht woran das liegen kann :(

Nehme ich die zeitliche Einschränkung raus, sind alle Teams dabei. Etwas weiter oben habe ich den DB Aufbau angehängt.


SQL-Code:
select t.name, count(i.issueID) as TotalIssue
from tb_teams t
full join tb_users u on u.fk_teamid = t.teamid
full join tb_issues i on i.fk_userid = u.userid
where
((i.CreationDate >= '03.03.2008 00:00:00')
 and (i.CreationDate < '09.03.2008 00:00:00')) or (i.CreationDate is null)

group by t.name
order by t.name
Thanx Marcus

Olli73 29. Apr 2008 17:57

Re: SQL "umbauen"
 
Hallo,

ich nehme mal an, dass die Teams, die gar keine Issues und die Teams, die Issues im genannten Zeitraum haben auftauchen, aber nicht die, die Issues in einem anderen Zeitraum haben. Wäre zumindest logisch, wenn man sich vorstellt, dass zuerst der JOIN ausgeführt wird und anschließend deine Bedingungen darüber laufen

Versuch doch mal die Bedingung mit in den Join reinzunehmen:

SQL-Code:
select t.name, count(i.issueID) as TotalIssue
from tb_teams t
full join tb_users u on u.fk_teamid = t.teamid
full join tb_issues i on i.fk_userid = u.userid and
  (i.CreationDate >= '03.03.2008 00:00:00') and (i.CreationDate < '09.03.2008 00:00:00')
group by t.name
order by t.name

NormanNG 29. Apr 2008 18:02

Re: SQL "umbauen"
 
Hi,

es macht keinen Unterschied, ob die Bedingungen direkt im Join oder im Where gesetzt sind.
Welche Daten fehlen denn?

[edit]
ich seh´gerade, du machst full joins und prüft dann auf [(i.CreationDate is null)].
Kann es sein, dass die Teams fehlen, die garkeine issues haben?
Versuchs doch mal mit LEFT JOIN...

Olli73 29. Apr 2008 18:35

Re: SQL "umbauen"
 
Zitat:

es macht keinen Unterschied, ob die Bedingungen direkt im Join oder im Where gesetzt sind.
Bist du sicher bzw. hast du es getestet. Bei mir macht es nämlich (mit anderen Daten) einen Unterschied.

alzaimar 29. Apr 2008 19:40

Re: SQL "umbauen"
 
Du willst also (1) Teams auflisten, und wenn die 'issues' haben, dann diese Zählen. Oder willst Du (2) nur die Teams aufzählen, die innerhalb des Zeitraumes 'issues' hatten und dann diese Teams und deren Anzahl auflisten?

Zu 1. fällt mir spontan sowas ein:

SQL-Code:
select t.name,
       coalesce (
         (select count (distinct i.issueID)
            from tb_issues i
                 join tb_users u on i.fk_userID = u.userID
           where u.fk_teamID = t.teamID
             and i.CreationDate Between '20080303' and '20080309 23:59:59')
         ,0) as Anzahl
from tb_teams t
order by t.name
Hier werden garantiert alle Teams aufgelistet sowie deren Issueanzahl im gewünschten Zeitraum.
Und zu 2.
SQL-Code:
select t.name,
       count(i.issueID) as TotalIssue
from tb_teams t
     join tb_users u on u.fk_teamid = t.teamid
     join tb_issues i on i.fk_userid = u.userid
where i.CreationDate Between '20080303' and '20080309 23:59:59'
group by t.name
order by t.name

NormanNG 30. Apr 2008 07:32

Re: SQL "umbauen"
 
Hi,


Zitat:

Zitat von Olli73
Zitat:

es macht keinen Unterschied, ob die Bedingungen direkt im Join oder im Where gesetzt sind.
Bist du sicher bzw. hast du es getestet. Bei mir macht es nämlich (mit anderen Daten) einen Unterschied.

@Olli73
Das dachte ich bisher immer :gruebel:
Hast du mal ein Beispeil für mich?

Olli73 30. Apr 2008 08:23

Re: SQL "umbauen"
 
Zitat:

Hast du mal ein Beispeil für mich?
@NormanNG:

Ich veruche mal ein einfaches Beispiel mit 2 Tabellen und wenigen Daten zu konstruieren:

SQL-Code:
Tabelle1 mit TeamA, TeamB, TeamC und Tabelle 2 mit Issues, wobei TeamA und TeamB jeweils 1 und TeamC keinen Issue hat:

select a.*, b.* from tabelle1 a left join tabelle2 b on b.team = a.team
ergibt dann:

TeamA 28.04.2008 ...
TeamB 30.04.2008 ...
TeamC <NULL>    ...

wenn ich dann anfüge "where b.datum = '28.04.2008' or b.datum is null" wird obiges Ergebnis(!) eingeschränkt und TeamB fällt dadurch weg, weil es die Bedingung nicht erfüllt:

TeamA 28.04.2008 ...
TeamC <NULL>    ...

schreibe ich aber anstatt(!) "where ..." dann "AND b.datum = '28.04.2008' wird die Bedingung bereits beim Aufbau des Joins(!) ausgewertet und man erhält:

TeamA <NULL>    ...
TeamB 30.04.2008 ...
TeamC <NULL>   ...
Ich hoffe mal, dass ich mich verständlich ausgedrückt habe.

NormanNG 30. Apr 2008 10:11

Re: SQL "umbauen"
 
Hi,

du schummelst :wink:


im Original stand ein full-join, und darauf bezog sich meine Anmerkung.
SQL-Code:
select t.name, count(i.issueID) as TotalIssue
from tb_teams t
full join tb_users u on u.fk_teamid = t.teamid
full join tb_issues i on i.fk_userid = u.userid and
  (i.CreationDate >= '03.03.2008 00:00:00') and (i.CreationDate < '09.03.2008 00:00:00')
group by t.name
order by t.name
Bei einem left-join hat du natürlich Recht.

Salomon 30. Apr 2008 10:51

Re: SQL "umbauen"
 
@alzaimar: Dein Fall 1 ist genau das was ich suche :) Damit mir sowas auch mal spontan einfällt habe ich mir erstmal ein SQL Buch bestellt ;) Auf die Abfrage wäre ich wohl so nie gekommen.
Ich brauche immer alle Teams, da ich in einem Report alle geschlossen den geöffneten Issues pro Team gegenüberstellen will.


Wenn ich eine weitere Tabelle joine, muss ich dann Felder darin dann auch auf NULL abfragen? Ich glaube nicht, oder? Sorry, wenn das eine "komische" Frage ist. Für mich ist das aber schon ein recht komplexes SQL Querry.

SQL-Code:
set transaction isolation level read uncommitted;    
select t.name as TeamName,
       coalesce ( 
         (select count (distinct i.issueID)
            from tb_issues i
                 join tb_users u on i.fk_userID = u.userID
                 join tb_history h on h.fk_issueid = i.issueid
           where u.fk_teamID = t.teamID
                and ((i.visibility = 1) or i.visibility is null) <== Auf NULL prüfen?                                   
                and ((h.action = 1) or h.action is null)
                and ((i.FK_IssueStatusID = 5) or i.FK_IssueStatusID is null)                                
 
                and ((h.ChangeDate >= '03.03.2008 00:00:00' /* -1 */ and h.ChangeDate < '09.03.2008 00:00:00')  
                 or (h.ChangeDate is null))                  
             ),0) as Anzahl
from tb_teams t
order by t.name
Das ich während des Joins schon die Datenmenge einschränken kann wusste ich auch noch nicht, hier lernt man doch immer viel dazu :) Die verschiedenen Join Varianten hatte ich in meinem ursprünlichen Query fast alle durchprobiert. Der Full oder left join brachten da das selbe Ergebnis.


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:22 Uhr.
Seite 2 von 3     12 3      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz