mySQL --> Etwas schwieriegers SELECT und Count Problem

Geshrec22

Grünschnabel
Hallo erstmal... habe in diesem Forum schon oft als "Leser" Hilfe gefunden....
Nun komme ich aber ned umhin selbst einmal eine Frage stellen zu müssen:
Folgendes ist mein Problem:
Ich baue gerade ein Foren-System(mit mySQL und Java): Die Threads sind alle in einer einzigen Table drin mit einem Feld "parentthreadid" Ist dieses "0" so weiss ich das die nachricht eine Eröffnungsnachricht ist, wenn nicht ist es eine Antwort etc.... Bis hierher ist die Sache ja noch relativ einfach, ABER: Ich möchte es irgendwie hinbekommen in einer einzigen SELECT-Abfrage sowohl die Gesamtzahl der Threads sowie die Gesamtzahl der Posts in einem Forum herauszukriegen... Auch das haut ja noch hin. Das Problem ist nur, das jedes Forum doppelt erscheint, einmal mit der (korrekten) Anzahl der Threads und einmal mit der (korrekten) Anzahl der Antworten. Die jeweils andere Anzahl ist 0 --> falsch
Distinct hilft scheinbar auch nicht... Anyways ich bin mit meinem Latein bzw. SQL am Ende und brauche Hilfe, hier mein SQL-Statement:



SELECT DISTINCT boardid, boardname, countThreads,countAnswers FROM (
SELECT
`boards`.`boardid`,
`boards`.`boardname`,
`boards`.`description`,
`threads`.`parentthreadid`,
COUNT(IF(threads.parentthreadid = 0, 1, null) ) AS `countThreads`,
COUNT(IF(threads.parentthreadid > 0, 1, null) ) AS `countAnswers`
FROM
`boards`
LEFT OUTER JOIN `threads` ON (`boards`.`boardid` = `threads`.`boardid`)
GROUP BY
`boards`.`boardid`,
`boards`.`boardname`,
`boards`.`description`,
`threads`.`parentthreadid`
) AS Test
 
Wie genau muss ich mir diese Ausgabe denn vorstellen?

Wie kriegst du zweimal ein Ergebnis, wenn du eine Variable abfrägst?

$daten = mysql_fetch_object($query);

$threads = daten->countthreads;


Wie muss ich mir da deine Ausgabe vorstellen?

cu shutdown
 
Das Problem ist das in dem ResultSet (sorry Java-Terminus) jedes Board 2 mal auftaucht
Beispiel: In "Programming" habe ich (testweise) 11 Threads und 0 Antworten dazu.
"Programming" taucht nur einmal auf. --> mui bien.
In "Offtopic" 0 threads, 0 Answers --> passt
Aber im Forum "Announcements" habe ich 2 Threads und 2 Antworten
Jetz steht des 2 mal drin, d.h. mein DISTINCT im Oberquery hat keinen effekt mehr
Ich erhalte einmal das Forum "Announcements" mit 0 Threads und 2 Answers und einmal mit 2 Threads uns 0 Answers.

Btw... Ich frage keine Variablen ab... das ist es ja gerade.... der Fehler liegt ja schon im Ergebnis der Abfrage. Ich möchte das diese korrekt ist.
 
Mit nem OuterJjoin gehts glaub ich nich so gut.

Probiers ma hiermit:

PHP:
SELECT 
'Hauptboards' as parentthreadid, 
count(  *  )  AS anzahl_antworten
FROM boards
WHERE parentthreadid = 0
UNION 
SELECT 
parentthreadid, count(  *  )  AS anzahl_antworten
FROM boards
WHERE parentthreadid > 0
GROUP  BY parentthreadid

Meine Test-Tabelle dazu. Sollte vom Prinzip her Deiner ähneln oder?

PHP:
CREATE TABLE `boards` (
  `parentthreadid` tinyint(2) unsigned NOT NULL default '0'
) TYPE=MyISAM;

INSERT INTO `boards` VALUES (0);
INSERT INTO `boards` VALUES (0);
INSERT INTO `boards` VALUES (0);
INSERT INTO `boards` VALUES (1);
INSERT INTO `boards` VALUES (2);
INSERT INTO `boards` VALUES (1);
INSERT INTO `boards` VALUES (2);
INSERT INTO `boards` VALUES (4);
INSERT INTO `boards` VALUES (3);
INSERT INTO `boards` VALUES (2);
INSERT INTO `boards` VALUES (4);
INSERT INTO `boards` VALUES (7);
INSERT INTO `boards` VALUES (2);
INSERT INTO `boards` VALUES (3);

Und das Ergebnis:

PHP:
+----------------+------------------+
| parentthreadid | anzahl_antworten |
+----------------+------------------+
| Hauptboards    |                3 |
| 1              |                2 |
| 2              |                4 |
| 3              |                2 |
| 4              |                2 |
| 7              |                1 |
+----------------+------------------+
6 rows in set (0.01 sec)
 
Danke für die nettgemeinten vorschläge, aber bis jetz haut aber auch nix hin....
ich werd hier noch wahnsinnig :rolleyes:
hier mal mein SQL-Code als SQL-Files zum testen....
das wird jetz etwas mehr...
Erstmal struktur und records der "threads"
PHP:
 SET FOREIGN_KEY_CHECKS=0;
 #----------------------------
 # Table structure for threads
 #----------------------------
 CREATE TABLE `threads` (
   `threadid` bigint(99) unsigned NOT NULL auto_increment,
   `parentthreadid` bigint(99) unsigned default '0',
   `boardid` int(10) unsigned NOT NULL default '0',
   `userid` bigint(20) unsigned default NULL,
   `subject` varchar(255) NOT NULL default '',
   `threadtext` longblob,
   `threadsvg` longblob,
   `postdate` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
   PRIMARY KEY  (`threadid`),
   KEY `userid` (`userid`),
   KEY `parentthreadid` (`parentthreadid`),
   KEY `threadcategoryid` (`boardid`),
   CONSTRAINT `threads_ibfk_2` FOREIGN KEY (`userid`) REFERENCES `users` (`ID_User`) ON DELETE SET NULL ON UPDATE CASCADE,
   CONSTRAINT `threads_ibfk_3` FOREIGN KEY (`boardid`) REFERENCES `boards` (`boardid`) ON DELETE CASCADE ON UPDATE CASCADE
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 #----------------------------
 # Records for table threads
 #----------------------------
 
 
 insert  into threads values 
 (1, 0, 1, 1, 'sdsdsd', '', '', '2001-01-01 00:00:00'), 
 (2, 0, 1, 1, 'asdasdasdasd', 'BRUZZ', '', '2001-01-01 00:00:00'), 
 (3, 0, 1, 1, 'asdasdasdasdasdBRUZZZZZZZZ', 'asdasdasdasd', '', '2001-01-01 00:00:00'), 
 (12, 0, 4, 1, '1,Announcement', '<span style=\"font-weight: bold;\">This is an TEST</span>', '', '2001-01-01 00:00:00'), 
 (13, 12, 4, 1, 'TestThread', '', '', '0000-00-00 00:00:00'), 
 (14, 12, 4, 1, 'asdasdasd', '', '', '0000-00-00 00:00:00'), 
 (15, 0, 1, 1, 'asdasd', 'asdasdasdasd', '', '0000-00-00 00:00:00'), 
 (16, 0, 1, 1, 'klöjljkljkljklj', 'lköjlööjöl', '', '0000-00-00 00:00:00'), 
 (17, 0, 1, 1, 'me', '<img src=\"http://fabi.cf-dev.de/infos/images//me_1.jpg\" />', '', '0000-00-00 00:00:00'), 
 (19, 0, 1, 1, 'g', '<br />', '', '0000-00-00 00:00:00'), 
 (24, 0, 1, 1, 'function validateForm(theForm){', '<br />', '', '0000-00-00 00:00:00'), 
 (37, 0, 1, 1, '', '', '', '0000-00-00 00:00:00'), 
 (38, 0, 1, 1, '', '', '', '0000-00-00 00:00:00'), 
 (39, 0, 1, 1, '', '', '', '0000-00-00 00:00:00'), 
 (40, 0, 1, 1, '', 'sdsdsd', '', '0000-00-00 00:00:00'), 
 (41, 0, 4, 1, 'This is my Thread', 'This is my Thread', '', '0000-00-00 00:00:00'), 
 (42, 0, 1, 1, 'Test tha Board', '<img hspace=\"0\" src=\"http://fabi.cf-dev.de/infos/images//me_2.jpg\" align=\"baseline\" border=\"0\" />', '', '0000-00-00 00:00:00'), 
 (43, 0, 1, 1, 'asdasd', 'asdasd', '', '0000-00-00 00:00:00'), 
 (44, 0, 1, 1, '', '', '', '0000-00-00 00:00:00'), 
 (45, 0, 1, 1, '', '', '', '0000-00-00 00:00:00'), 
 (46, 0, 1, 1, '', '', '', '0000-00-00 00:00:00'), 
 (47, 0, 1, 1, '', '', '', '0000-00-00 00:00:00'), 
 (48, 0, 1, 1, '', '', '', '0000-00-00 00:00:00'), 
 (49, 0, 1, 1, '', '<br />', '', '0000-00-00 00:00:00'), 
 (50, 0, 1, 1, '', '', '', '0000-00-00 00:00:00'), 
 (51, 0, 1, 1, '', '<br />', '', '0000-00-00 00:00:00'), 
 (52, 0, 1, 1, '', '<br />', '', '0000-00-00 00:00:00'), 
 (53, 0, 1, 1, '', '', '', '0000-00-00 00:00:00'), 
 (54, 0, 1, 1, '', '', '', '0000-00-00 00:00:00'), 
 (55, 0, 1, 1, '', '<br />', '', '0000-00-00 00:00:00'), 
 (56, 0, 1, 1, '', '', '', '0000-00-00 00:00:00'), 
 (57, 0, 1, 1, '', '', '', '0000-00-00 00:00:00'), 
 (58, 0, 1, 1, '', '', '', '0000-00-00 00:00:00'), 
 (59, 0, 1, 1, '', '<br />', '', '0000-00-00 00:00:00'), 
 (60, 0, 1, 1, '', '<br />', '', '0000-00-00 00:00:00'), 
 (61, 0, 1, 1, '', '', '', '0000-00-00 00:00:00');

Und dann noch Struktur und Records der Boards:
PHP:
 SET FOREIGN_KEY_CHECKS=0;
 #----------------------------
 # Table structure for boards
 #----------------------------
 CREATE TABLE `boards` (
   `boardid` int(10) unsigned NOT NULL auto_increment,
   `boardname` varchar(255) NOT NULL default '',
   `description` blob,
   PRIMARY KEY  (`boardid`)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 #----------------------------
 # Records for table boards
 #----------------------------
 
 
 insert  into boards values 
 (1, 'Programming', ''), 
 (2, 'Support', ''), 
 (3, 'Misc / Offtopic', ''), 
 (4, 'Announcements', '');

Viel Spass damit... wenn das einer schaffen würde.. ich wär dankbar mein leben lang...
Das ist son scheiss... ich bastel daran schon 3 oder 4 h. rum insgesamt...
 
PHP:
SELECT
  `boards`.`boardid`,
  `boards`.`boardname`,
  `boards`.`description`,
  `threads`.`parentthreadid`,
  SUM(IF(threads.parentthreadid = 0, 1, 0) ) AS `countThreads`,
  SUM(IF(threads.parentthreadid > 0, 1, 0) ) AS `countAnswers`
FROM
  `threads`
LEFT JOIN
  `boards` ON (`boards`.`boardid` = `threads`.`boardid`)
GROUP BY
  `boards`.`boardid`

Liefert:
Code:
+---------+---------------+-------------+----------------+--------------+--------------+
| boardid | boardname     | description | parentthreadid | countThreads | countAnswers |
+---------+---------------+-------------+----------------+--------------+--------------+
|       1 | Programming   |             |              0 |           32 |            0 |
|       4 | Announcements |             |              0 |            2 |            2 |
+---------+---------------+-------------+----------------+--------------+--------------+
Ist es das? Hab' ich gewonnen? ;)

Die Ausgabe des Feldes `threads`.`parentthreadid` macht allerdings in dieser Abfrage kaum Sinn, weil einfach das Ergebnis des ersten Satzes in der Gruppe ausgegeben wird.

Martin
 
Oh ja Resalb das hast du ;)
Das einzige was noch nicht ok ist, das deine Abfrage nur boards liefert wo bereits etwas eingetragen wurde.... Könnte man das vielleicht noch irgendwie... ?
Entschuldigt die blöden Fragen aber ich bin gerade erst in mySQL eingestiegen... Es ist eine grossartige Datenbank aber SQL selber schreiben .... naja bin Access-verwöhnt bisher... *ähem*
 
Zuletzt bearbeitet:
Juhu ich habs hingekriegt:
Das ist das resultierende Statement....
PHP:
  SELECT
    `boards`.`boardid`,
    `boards`.`boardname`,
    `boards`.`description`,
    `threads`.`parentthreadid`,
    SUM(IF(threads.parentthreadid = 0, 1, 0) ) AS `countThreads`,
    SUM(IF(threads.parentthreadid > 0, 1, 0) ) AS `countAnswers`
  FROM
    `threads`
  LEFT JOIN
    `boards` ON (`boards`.`boardid` = `threads`.`boardid`)
  GROUP BY
    `boards`.`boardid` 
  
  UNION ALL
  
  SELECT
    `boards`.`boardid`,
    `boards`.`boardname`,
    `boards`.`description`,
  `threads`.`parentthreadid`,
    '0' AS countThreads,
    '0' AS countAnswers
  FROM
    `threads`
  RIGHT JOIN
    `boards` ON (`boards`.`boardid` = `threads`.`boardid`)
  WHERE boards.boardid NOT IN (SELECT DISTINCT boardid FROM threads)
  GROUP BY
    `boards`.`boardid`

Ich musste nur Resalbs (perfekten, spitzenmässigen, wunderbaren :)) Code noch ein bisschen erweitern und kriege jetz auch Boards angezeigt, welche bisher noch keinen Beitrag haben.

Nochmal vielen Dank für die Hilfe an alle!
 

Neue Beiträge

Zurück