Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

Abfrage mit SELECT COUNT

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von helico, 21 Januar 2013.

  1. helico

    helico Benutzer

    Hallo
    Habe so gut wie keine Ahnung von Datenbanken. Dafür ein altes, funktionierendes Reservierungssystem mit Mysql. Das möchte um eine kleinen Textteil erweitern.
    So sieht es bisher aus:


    <TABLE BORDER="0" CELLPADDING="2" CELLSPACING="2">
    <TR BGCOLOR="#99BBAE">
    <TD width="69" ALIGN=CENTER><BR></TD>
    <? $result = mysql_query("SELECT COUNT(tCat_desc) AS row FROM tcat WHERE tCat_lang = 1");
    // (tCat_desc) ist eine Zimmerbeschreibung der Tabelle tCat. Es soll noch ein Link dazu(info_popup)kommen.
    Jetzt könnte ich es einfach in die gleiche Tabellenksektion der Tabelle tCat (tCat_desc + <ahref="#">Link-popup</a>) schreiben. Ich möchte aber verhindern, daß der Link info-popup im nächsten Schritt (Buchungsbestätigung per Email, da wird wieder tCat_desc aufgerufen) nicht wieder aufgeführt wird.
    Muß ich das so machen:
    <? $result = mysql_query("SELECT COUNT(tCat_desc) AS row FROM tcat WHERE tCat_lang = 1");
    <? $result = mysql_query("SELECT COUNT(tCat_link-popup) AS row FROM tcat WHERE tCat_lang = 1");
    oder kann man beides zusammenfassen?

    Ich habe wirklich keine Ahnung, hoffe aber auf einen gnädigen Hinweis und werde danach niemanden weiter langweilen.
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Ich bin mir absolut nicht sicher, was Du für eine Botschaft an uns im Text versteckt hast, aber vielleicht willst Du das count(*) zweier Tabellen in einem Rutsch abfragen.

    Angenommen, die Tabellen heißen 'foo' und 'werte':

    Code:
    test=*# select 'foo' as table, count(1) from foo union select 'werte', count(1) from werte;
     table | count
    -------+-------
     foo   |   100
     werte |     6
    (2 rows)
    
    Das sollte sogar 1:1 mit MySQL so gehen.


    Andreas
     
  3. helico

    helico Benutzer

    Hallo Andreas
    Ja mit einem Rutsch abfragen:

    CREATE TABLE `tcat` (
    `tCat_id` smallint(5) unsigned NOT NULL auto_increment,
    `tCat_desc` varchar(60) default NULL,
    `tCat_link-popup` varchar(255) default NULL,
    `tCat_price` int(11) default NULL,
    `tCat_lang` smallint(5) unsigned NOT NULL default '0',
    `tCat_rooms` smallint(6) NOT NULL default '0',
    `tCat_type` smallint(6) NOT NULL default '0',
    PRIMARY KEY (`tCat_id`)
    ) TYPE=MyISAM AUTO_INCREMENT=77 ;

    --
    -- Daten für Tabelle `tcat`
    --

    INSERT INTO `tcat` VALUES (17, 'Appartamento XXL, 60m², 2 camere di letto., salone', 'link-popup ITAL', 150, 4, 5, 2);
    INSERT INTO `tcat` VALUES (16, 'Appartamento XL, 40m², 1 camera di letto., salone', 'link-popup ITAL', 100, 4, 5, 1);
    INSERT INTO `tcat` VALUES (13, 'Apartment XXL, 60m², 2 Bedrooms, Saloon', 'link-popup ENG150, 2, 5, 2);
    INSERT INTO `tcat` VALUES (12, 'Apartment XL, 40m², 1 Bedroom., Saloon', 'link-popup ENG', 100, 2, 5, 1);
    INSERT INTO `tcat` VALUES (11, 'Apartment XXL, 60m², 2 Schlafz, Salon', 'link-popup GERM', 150, 1, 5, 2);
    INSERT INTO `tcat` VALUES (10, 'Apartment XL, 40m², 1 Schlafz., Salon', 'link-popup GERM', 100, 1, 5, 1);


    Diese beiden Abfragen halt zusammen als eine Zeile. (gefragt wird hier nach increment 11 und 10 weil tCat_lang = 1 für "deutsch" steht )
    <? $result = mysql_query("SELECT COUNT(tCat_desc) AS row FROM tcat WHERE tCat_lang = 1");
    <? $result = mysql_query("SELECT COUNT(tCat_link-popup) AS row FROM tcat WHERE tCat_lang = 1");
    Wie schreib ich das in einem Befehl?

    Vielen Dank schon 'mal jetzt.

    Dietmar
     
  4. akretschmer

    akretschmer Datenbank-Guru


    Okay, kurze Demo:

    Code:
    test=*# select * from foo;
     c1 | c2 | c3
    ----+----+----
      1 |  2 |  3
      1 |  1 |  2
      1 |  1 |  1
    (3 rows)
    
    test=*# select
      sum(case when c1 = 1 then 1 else 0 end) as sum_c1,
      sum(case when c2 = 1 then 1 else 0 end) as sum_c2,
      sum(case when c3 = 1 then 1 else 0 end) as sum_c3
    from foo;
     sum_c1 | sum_c2 | sum_c3
    --------+--------+--------
          3 |      2 |      1
    (1 row)
    
    Prinzip sollte klar sein, ist jetzt PostgreSQL, sollte aber mit MySQL fast genauso gehen (ich glaub, Du mußt statt CASE aber IF nehmen).

    Eine Frage sei gestattet:

    Daß ich von MySQL nicht viel halte, da mache ich kein Hehl draus, aber muß es denn wirklich unbedingt auch noch MyISAM als Engine sein?

    Das ist, sorry, technologischer Schrott des letzten Jahrtausends.


    PS.: wie viele unterschiedliche Werte kommen in tCat_lang vor? Evtl. lohnt sich der Einsatz eines Indexes.



    Andreas
     
  5. helico

    helico Benutzer

    Hallo Andreas

    Du hast vollkommen Recht - Schrott aus dem letzten Jahrhundert.
    Ich habe den Programmierer noch mit D-Mark bezahlt.
    Also tcat ist die Tabelle für die verschiedenen Zimmertypen. Im Beispiel sind es 2 verschieden Zimmer, aber in 3 verschiedenen Sprachen( tcat_lang, deutsch, englisch, italienisch) Das habe ich jetzt nachträglich selber gemacht:
    `tCat_link-popup` varchar(255) default NULL,
    Im Original ist das ohne dieses Feld.
    Die Abfrage: <? $result = mysql_query("SELECT COUNT(tCat_desc) AS row FROM tcat WHERE tCat_lang = 1");
    enthält nichts, was irgendwie berechnet werden soll, tCat_desc enthält nur den text der Zimmerbeschreibung, und
    tCat_link-popup soll auch nur Text zu einem Link enthalten für weitere Informtionen über das Zimmer (html Seite mit text und Bildern in einem Popup-Fenster oder mit jQuery.

    wie viele unterschiedliche Werte kommen in tCat_lang vor? Es gibt fünf verschiedene Werte, von 1 -5 wobei 1 für deutsch2, für englisch usw. Das Programm läuft in 5 verschiede Sprachen.

    Gruß
    Dietmar
     
  6. akretschmer

    akretschmer Datenbank-Guru

    *smile*


    Du kommst jetzt zurecht, oder brauchst noch Hilfe?

    Vermutlich ist also das Feld in vielen Abfragen Teil der WHERE-Condition und enthält exakt einen der möglichen Werte. Daher könnte ein Index auf dem Feld Abfragen beschleunigen, da so nur 1/5 der Datensätze in Betracht kommen.

    Ein 'sauberes' Tabellendesign würde da übrigens eine weitere Tabelle haben, mit den möglichen Sprachen und einer ID als PRIMARY KEY, und Dein tcat_lang wäre ein FOREIGN KEY auf diese Tabelle. Aber - MyISAM kann das alles nicht. Was macht Dein Programm, wenn da mal ein Spaßvogel eine 6 einträgt?

    Andreas
     
  7. helico

    helico Benutzer

    Hallo Andreas

    Kann der Spaßvogel als admin nicht. Das Auswahlfeld geht nur bis 5.

    Eigentlich wollte ich nur diese beiden Befehle
    <? $result = mysql_query("SELECT COUNT(tCat_desc) AS row FROM tcat WHERE tCat_lang = 1");
    <? $result = mysql_query("SELECT COUNT(tCat_link-popup) AS row FROM tcat WHERE tCat_lang = 1");
    zu einem zusammenfassen,von mir aus auch ohne die Sprachkennungsnummern in tCat_lang = von 1-5.

    Also vielleicht das hier in der richtigen Schreibweise
    <? $result = mysql_query("SELECT COUNT(tCat_desc) + (tCat_link-popup)AS row FROM tcat");

    Bin, wie schon gesagt, Mysql-Analphabet und mir geht es nur um diese eine Abfrage.
    Das Ganze funktioniert ohne "tCat_link-popup" so wie hier seit Jahren ganz gut:

    http://www.securebookers.net/sb_test1nodiscount/de/time_c-d.php

    Gruß Dietmar
     
  8. akretschmer

    akretschmer Datenbank-Guru

    Du es es nicht ganz verstanden: es ging um 'referentielle Integrität'. Aber vielleicht willst es ja auch nicht verstehen...


    ungeteset: select count(tCat_desc), count(tCat_link-popup) as row from tcat where tCat_lang = 1;

    Aber beide Spalten werden den selben Inhalt haben...

    Andreas
     
  9. helico

    helico Benutzer

    Vielen Dank Andreas

    Jetzt weiß ich, daß ich die Abfragen durch ein Leerzeichen getrennt in die Seite mit der Verfügbarkeit einsetzen muß.

    Habe noch ein kleines Problem entdeckt, aber für die Lösung würde ich dann eine Belohnung anbieten.

    Bei Interesse bitte kurze Nachricht.

    LG Dietmar
     
  10. akretschmer

    akretschmer Datenbank-Guru

    Frag doch einfach ...

    Andreas
     
  11. helico

    helico Benutzer

    Hallo Andreas

    Also frage ich einfach:
    Von Anfang an gibt es mit der Tabelle für die Belegung ein Problem, daß ich jedes Jahr mit einem Trick manuell ausgleichen muß.
    Hier erstmal die Tabelle:

    CREATE TABLE `toccupancy` (
    `tOccupancy_id` smallint(5) unsigned NOT NULL auto_increment,
    `tOccupancy_day` date default NULL,
    `tOccupancy_rooms` smallint(6) default NULL,
    `tOccupancy_type` smallint(6) default NULL,
    PRIMARY KEY (`tOccupancy_id`),
    KEY `Occupancy` (`tOccupancy_day`,`tOccupancy_type`)
    ) TYPE=MyISAM AUTO_INCREMENT=5222 ;

    Reserviert jemand ein Zimmer z.B. vom 5.2. 2013 bis einschließlich 10.2.2013, wird, wenn noch keine Reservierung vorliegt, für jeden Tag in tOccupancy_rooms eine 1 eingetragen. Die 1 steht für die Anzahl der belegten Zimmer an diesem Tag.
    Die nächste Reservierung für den gleichen Zimmertyp wäre jetzt zum Beispiel 2.2.201 bis ein einschließlich 13.2.2013.
    Jetzt steht vom 2.2. 2013 bis einschließlich 4.2.2013 eine 1, vom 5.2. 2013 bis einschließlich 10.2.2013 jeweils eine 2 und vom 11.2. 2013 bis einschließlich 13.2.2013 sollte wieder eine 1 stehen. Die 1 vom 11.2. 2013 bis einschließlich 13.2.2013 fehlt aber. Es wird nichts eingetragen.
    Nach einigen Reservierungen wäre natürlich alles durcheinander und niemand würde wissen, was los ist.

    Ich mache jetzt folgendes:
    Ein Jahr im voraus reserviere ich jeden Tag des Jahres und lösche danach alles. Dann hat dieSpalte tOccupancy_rooms jeden Tag bei der Anzahl der Reservierungen plötzlich eine Null stehen. Sobald überall eine Null bzw. der richtige Wert steht, funktioniert alles einwandfrei.

    tOccupancy hat ja default NULL, aber anscheinend muß die Null auch wirklich eingetragen sein, damit es verstanden-gelesen werden kann.
    So kommen pro Jahr und Zimmertyp 365 Tabellenzeilen, bei 9 Zimmertypen ist das einiges, siehe Myisam oben.

    Den Fehler hatte ich aber erst gemerkt, als ich den Programmierer schon bezahlt hatte. Danach gab es dann natürlich auf der Lieferantenseite einige Terminschwierigkeiten. Kurzum, die Kommunikation zwischen uns flaute etwas ab.
    Da das Programm nie so der richtige Knaller wurde und ich es nur für drei kleine Häuser auf Zakynthos einsetze, bei denen ich für die Besitzer die Buchungen mache, kann ich mir auch weiterhin auf meine Art helfen, aber schön ist das eigentlich nicht.
    Falls Dir ein Licht aufgeht, laß es leuchten.

    LG Dietmar
     
  12. akretschmer

    akretschmer Datenbank-Guru


    Wenn ich das richtig verstehe (bin mir nicht ganz sicher) wird beim Eintragen der vorhandene Wert um 1 erhöht. Das geht, solange da ein Wert drin steht, wenn NULL drin steht (nicht0, sondern NULL), dann geht das nicht. Demo:

    Code:
    test=*# create table null_test(id serial, value int);
    NOTICE:  CREATE TABLE will create implicit sequence "null_test_id_seq" for serial column "null_test.id"
    CREATE TABLE
    test=*# insert into null_test (value) values (0);
    INSERT 0 1
    Time: 0,323 ms
    test=*# insert into null_test (value) values (NULL);
    INSERT 0 1
    Time: 0,160 ms
    test=*# insert into null_test (value) values (1);
    INSERT 0 1
    Time: 0,181 ms
    test=*# select * from null_test;
    id | value
    ----+-------
      1 |    0
      2 |
      3 |    1
    (3 rows)
     
    Time: 0,197 ms
    test=*# update null_test set value = value + 1;
    UPDATE 3
    Time: 0,258 ms
    test=*# select * from null_test;
    id | value
    ----+-------
      1 |    1
      2 |
      3 |    2
    (3 rows)
    
    Das Tabellendesign bei Dir ist, ähm, ich sag mal nix weiter ...

    Was ist nicht ganz verstehe: daß es (angeblich) mit dem ersten Eintrag klappt. Aber da müßte man genau schauen, was da programmiert wurde, was wann eingetragen wird etc.


    Andreas
     
  13. helico

    helico Benutzer

    Also der Wert, der eingetragen wird, hängt davon ab, wieviel Zimmer gebucht werden. es könnten auch 1000 sein.
    (Wäre das schön für mich, aber 1000 ist wohl eher ein Gefängnis)
    Der erste Eintrag klappt immer und auch alle anderen, nur wenn nach einem Eintrag ein Tag oder Datum kommt, an dem noch gar kein Zimmer vermietet ist, also leer und auch keine 0 eingetragen ist, dann bricht es ab.

    LG Dietmar
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden