PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : COUNT(*) auf mehrere Tabellen anwenden innerhalb einer SELECT-Anweisung


Cord Worthmann
05.07.2002, 20:56
hi folks!

ich habe da mal ne frage...

wenn ich in eine SELECT-anweisung mehrere tabellen einbeziehe, kann ich dann COUNT(*) auf jede einzelne tabelle anwenden?
wenn ja, wie?

ich habe da mal ein bisschen rumprobiert:

SELECT COUNT(tab1.ID) AS ID1, COUNT(tab2.ID) AS ID2, COUNT(tab3.ID) AS ID3 FROM tab1, tab2, tab3

dabei werden leider alle drei ermittelten werte miteinander multipliziert (und ID1, ID2, ID3 bekommen alle das produkt aus allen dreien als wert) - so geht das nicht!

ihr vermutet wahrscheinlich schon, was ich damit bezwecken will - ich möchte in einer einzigen abfrage für die stats meiner web-app die anzahl aller einträge aus verschiedenen tabellen ermitteln.

also, sieht da wer eine möglichkeit?


grtz
chief


Jonas
06.07.2002, 15:35
Klar geht das (so) nicht ;)

Überleg doch mal:
Du holst die Zeilen aus tab1, tab2 und tab3, ergo muss MySQL (oder welche DB auch immer) auch alle möglichen kombinationen dieser 3 Tabellen raussuchen, und das ergibt eben die Produkte der Zeilenanzahlen der 3 Tabellen.

Was du machen könntest wäre folgendes:

SELECT MAX(tab1.id), MAX(tab2.id), MAX(tab3.id) FROM tab1, tab2, tab3;

Allerdings ist da das Problem, daß er ja nicht die Zeilen zählt, sondern den Maximalen Wert der id holt. Deswegen solltest du nach jedem Löschen in einer der Tabellen es so machen, daß du die Gesamte Tabelle in einen Array schmeisst (kannst ja schon die fertigen INSERTs auf das Array schreiben), dann ein
DELETE FROM tabX;
machst und dann wieder die Daten reinschmeisst

Denn wenn du einfach ne zeile löschst, wird der id-wert ja trotzdem nicht mehr vergeben -> du bekommst falsche MAX-Werte...

sami
06.07.2002, 16:34
dass es dafür keine direkte lösung gibt, stimmt.
aber jones, du meinst das hoffentlich ned ernst, dass du dich 1. aufs autoincrement so verlässt (das muss ned zwingend stimmen) und 2. vA dass du bei jedem löschen die tabelle neu schreiben willst.
ich nehme an, du machst das aus php heraus, da kannst mal versuchen, 3 selects in 1 query zu machen, vielleicht geht das. also:
SELECT COUNT(ID) AS ID1 FROM tab1;
SELECT IDCOUNT() AS ID2 FROM tab2;
SELECT COUNT(ID) AS ID3 FROM tab3;
folgendes dürfte bei jeder anständigen db funktionieren (bei mysql türlich ned, das kennt keine subselects):
SELECT ID1, ID2, ID3
FROM (SELECT COUNT(ID) AS ID1 FROM tab1),
(SELECT COUNT(ID) AS ID2 FROM tab2),
(SELECT COUNT(ID) AS ID3 FROM tab3);

Cord Worthmann
06.07.2002, 19:18
@jonas:
stimmt, das ist mir gar nicht aufgefallen, dass ich ja geradewegs die anweisung dazu gebe, dass die anzahlen miteinander multipliziert werden *ggg*
('bin wie vor den kopf geschlagen!)

@sami: ne, ist ausnahmsweise mal ASP und kein PHP - und mein hauptprob bei der ganzen SQL-geschichte (mal abgesehen von dieser anfrage hier) dabei ist, dass die ganze chose kompatibel für Access, M$ SQL, MySQL (und am besten auch noch Oracle) sein soll (...stöhn!)

an subselects hatte ich auch schon gedacht - dass MySQL diese nicht unterstützt, wusste ich noch gar nicht.


aber auf jeden fall vielen dank euch beiden.


grtz
chief

Jonas
06.07.2002, 20:01
Original geschrieben von sami
[B]dass es dafür keine direkte lösung gibt, stimmt.
aber jones, du meinst das hoffentlich ned ernst, dass du dich 1. aufs autoincrement so verlässt (das muss ned zwingend stimmen) und 2. vA dass du bei jedem löschen die tabelle neu schreiben willst.

Kommt ganz drauf an, was es für ne Tabelle ist.
Wenn es natürlich z.B. eine Tabelle für Who is Online in einem Forum wäre, sicher nicht ;-)
Aber eine Tabelle wo selten mal ein Eintrag gelöscht wird etc - warum nicht?
Und wegen der zuverlässigkeit: bei MySQL jedenfalls wird, wenn man die ganze Tabelle löscht, das alles ja auch auf 0 gesetzt, und deswegen sollte das schon passen....

Cord Worthmann
06.07.2002, 21:12
da sich die stats aus insgesamt 7 verschiedenen tabellen rekrutieren, habe ich das nun ganz anders gemacht.
einfach eine neue tabelle eingeführt, welche die count-werte der bewussten anderen tabellen beinhaltet - wird in einer der 7 tabellen ein datensatz hinzugefügt oder einer entfernt, dann wird einfach die stats-tabelle geupdated, und fertig isses.
so kann ich problemlos auf einen schlag alle count-werte erfahren, und muss dabei keine komplizierten abfragen schreiben, die jede DB wieder anders versteht.


grtz
chief

sami
06.07.2002, 23:25
ich hoffe, ich trete dir nun nicht zu nahe Brodie, aber damit machst du deinem status "Hobby Coder" alle ehre.
das ist sehr unzuverlässig und braucht mehr ressourcen.
wieso willst du eigentlich unbedingt nur 1 abfrage dafür haben?
btw, meine variante 1 kannst auch mal mit asp versuchen.

Cord Worthmann
07.07.2002, 01:06
nope, es funzt so nicht mit ASP - die jet-engine akzeptiert keine weitere anweisung nach einem abschliessenden semikolon...

ich verstehe nun auch eigendlich nicht so genau, worin du das problem meiner (zugegeben etwas 'billigen') variante siehst.
schau, 3 tabellen repräsentieren den rubriken-katalog der 'info-archive' meiner web-app (oberste verzeichnisebene = archiv(tab), folgende = kategorie(tab), unterste = thema(tab)).
jedesmal, wenn der site-admin ein thema, eine kategorie oder ein archiv dem katalog zufügt, wird automatisch ein update in der statistik-tabelle ausgeführt.
natürlich auch dann, wenn eine der obigen rubriken entfernt wird.
da wird sowieso laufend innerhalb des katalogs geupdated - also, angenommen, ein thema wird erstellt, dann wird z.b. das last-update-datum der übergeordneten kategorie sowie des übergeordneten archivs automatisch auch aktualisiert.

die nächste, vierte tabelle ist die mit den daten, also den inhalten des katalogs.
diese ist gewissermassen das herzstück, ähnlich der posts-tabelle eines foren-systems.
wird ein neuer beitrag erstellt, kann ebenfalls in einem zuge die statistik-tabelle aktualisiert werden.
ebenso, wenn ein eintrag entfernt wird.

tabelle 5 und 6 sind den previews und den reviews gewidmet, welche die benutzer der anwendung schreiben können.
hier das gleiche prozedere wie oben...

die letztendlich letzte tabelle ist natürlich die memberstabelle - und auch hier kann ganz problemlos bei jeder änderung der datensätze (sprich members) ein update der statistik vorgenommen werden.

ich möchte das einfach gerne in eins haben, damit nicht ganze 7 queries ausgeführt werden müssen jedesmal, wenn das ausgabe-script aufgerufen wird.
denn dafür ist die statistik dann doch etwas zu nebensächlich - sie ist halt informatives beiwerk wie bei einem board, aber nicht lebensnotwendig.

je nach verzeichnistiefe im rubriken-katalog beziehungsweise sonstiger aktionen wie eintragen, editieren von listings usw. werden so schon bei jedem seitenaufruf zwischen 10 und 17 selects durchgeführt.
und ich muss bei der programmierung einfach auch berücksichtigen, dass evtl. jemand (was gewiss auch oft genug der fall sein wird) die ganze chose nur mit access betreibt...
und bei maximal 255 gleichzeitigen operationen in access kann ich nicht mit sql-queries handhaben, als ob es kein morgen mehr gäbe *g*.

verstehst du meine situation?

nochmal zur näheren erleuterung:
das ganze ist konzeptioniert als eine art online-ressourcen/datenquelle, die ein admin wie ein forensystem verwalten kann.
d.h., anstelle foren halt archive (mit kategorien und themen als weitere aufsplittungen der bereiche).
es gibt eine umfangreiche member-verwaltung mit user-klassen, vips, noch speziellerer rechtevergabe, wie in einem board.
dazu die verwaltung und katalogisierung der unterschiedlichen, zu archivierenden daten-arten.
das untere management übernehmen operatoren (quasi daselbe wie mods) - nur sind auch deren rechte sehr viel spezieller als die eines board-mods, da sie eine sehr grosse bandbreite von aktionen ausführen dürfen (oder auch nicht ;-) ) - als da wären themen/kategorien erstellen, editieren, verschiebn, löschen, themen oder kategorien ex/importieren, die einträge ihres archivs verwalten, archiv warten usw...

das ganze muss man sich im grunde wirklich wie ein foren-system vorstellen - nur dass halt keine postings sondern informationen, links, scripts, bilder, texte etc. gesammelt und verwaltet werden.
als voll-administrierbare und auf den einsatz in einer community ausgelegte geschichte übrigens ein absolutes novum, wenn ich mich nicht irre...

von wegen 'hobby-coder'...
sicher bin ich nicht die grosse leuchte in sql - aber sämlicher aufwand liess sich bisher sehr gut mit unterschiedlichen joins ohne grossartigen einsatz von sql-funktionen bewältigen.
somit ist das nun gewissermassen neuland gewesen für mich.
aber, wie ich bereits oben erwähnt hatte, muss ich ganz allgemein auch recht vorsichtig mit meinen sql-statements sein, da das ganze mindestens unter access, ms-sql und mysql laufen können soll.


grtz
chief

Cord Worthmann
08.07.2002, 12:44
hehehehe...

nach langem rumprobieren habe ich nun doch endlich die ultimative lösung gefunden, COUNT(*) von allen tabellen in einem einzigen querie zu erlangen:


SELECT
(SELECT COUNT(*) FROM tab1) AS total1,
(SELECT COUNT(*) FROM tab2) AS total2,
(SELECT COUNT(*) FROM tab3) AS total3,
(SELECT COUNT(*) FROM tab4) AS total4,
(SELECT COUNT(*) FROM tab5) AS total5,
(SELECT COUNT(*) FROM tab6) AS total6,
(SELECT COUNT(*) FROM tab7) AS total7
FROM tab1 GROUP BY 1,2,3,4,5,6,7


wer hätte das gedacht *g*


grtz
chief

sami
08.07.2002, 15:07
Chief Brodie:
das resultat unterscheidet sich doch ned von meiner variante 2.
und wozu das group by?
und eben, diese subselects funktionieren ned in mysql.

Cord Worthmann
14.07.2002, 04:49
Original geschrieben von sami
Chief Brodie:
das resultat unterscheidet sich doch ned von meiner variante 2.
und wozu das group by?
und eben, diese subselects funktionieren ned in mysql.
nun, ob das resultat sich von deiner variante 2 unterscheiden würde, konnte ich nicht feststellen, da sie in dieser form als unverträglich zurückgewiesen wurde ;-)

das group by ist wirklich unsinn!

mysql verarbeitet keine sub-selects...
das ist falsch, wie ich inzwischen feststellen konnte - mysql kennt lediglich keine foreign-keys.


grtz
chief

Jonas
14.07.2002, 13:13
Original geschrieben von Chief Brodie
mysql verarbeitet keine sub-selects...
das ist falsch, wie ich inzwischen feststellen konnte - mysql kennt lediglich keine foreign-keys.

Hä? MySQL kann doch keine Subselects, oder?

Cord Worthmann
14.07.2002, 13:47
hehehehe... sorry!

ich muss mich korrigieren - ist natürlich richtig, dass es keine sub-selects kann (ein irrtum meinerseits)...


grtz
chief