Datenbanken

Datenbanken

Posts 1-10 of 17
  • Stefan Frech
    Stefan Frech
    The company name is only visible to registered members.
    Select aus zwei verschiedenen Tabellen
    Guten Tag allerseits

    Ich möchte ein Ergebnis aus einer MySQL Datenbank und bin mir nicht sicher, ob das mit einer einzigen Query lösbar ist. Wenn möglich sollte die Query auch MySQL Version 3/4 kompatibel sein, d.h. keine verschachtelte Query. Ist aber nicht zwingend.

    Ich habe zwei Tabellen die etwa so aufgebaut sind:

    CREATE TABLE file (
    user char(20) NOT NULL default '',
    title char(70) NOT NULL default '',
    ...
    public enum('0','1') default 0 not null
    );

    CREATE TABLE folder (
    user char(20) NOT NULL default '',
    title char(70) NOT NULL default '',
    ...
    public enum('0','1') default 0 not null
    );


    Ich möchte alle "user" die in der Tabelle "file" oder "folder" mindestens ein Feld "public" auf den Wert '1' gesetzt haben, und zusätzlich jeweils die Anzahl der "public" Felder. Mit zwei Queries krieg ich das gut hin:

    SELECT user, count(*) FROM file WHERE public='1' GROUP BY 'user';
    SELECT user, count(*) FROM folder WHERE public='1' GROUP BY 'user';

    Nun, kann ich das auch mit einer Query, sodass ich nachher das folgende Ergebnis hab?

    user count_files count_folders
    ============================
    Hans 27 8
    Fritz 334 27
    ...

    Vielen Dank für Eure Hilfe und beste Grüsse, Stefan
  • User photo
    Peter Raschendorfer
    (not a XING member)
    Re: Select aus zwei verschiedenen Tabellen
    Hallo Stefan,

    wenn jeder User jeweils immer nur in einer der beiden Tabellen vorkommen kann geht das am einfachsten mit UNION.

    SELECT....
    UNION
    SELECT....

    UNION geht aber bei MySQL erst ab Version 4.

    Oder kann ein User in beiden Tabellen vorkommen und muss dann über beide summiert werden?

    In anderen Datenbanken kann so etwas leicht mit einem FULL OUTER JOIN gelöst werden. Funktioniert aber leider nicht in MySQL. Es gibt einen Workaround dafür, der aber ebenfalls UNION benötigt...

    Eine Tabelle mit einem Kennzeichen, ob es sich um ein File oder einen Folder handelt, wäre natürlich die einfachste Lösung. Aber es wird wahrscheinlich Gründe dafür geben, dass zwei Tabellen angelegt wurden....

    LG Peter
  • Michael Steiger
    Michael Steiger
    The company name is only visible to registered members.
    Re^2: Select aus zwei verschiedenen Tabellen
    Wie schaffst du mit einem UNION, dass Werte aus 2 SELECTS (count_files, count_folders) nachher in einer Zeile aufscheinen?
    Mit dem UNION kämen ja zwei Zeilen heraus, was der OP aber nicht wollte.
  • Lars Pohlmann
    Lars Pohlmann    Premium Member
    The company name is only visible to registered members.
    Re: Select aus zwei verschiedenen Tabellen
    ohne subqueries fällt mir da nix ein...

    select user, sum(file) as files, sum(folder) as folders from (

    SELECT user, 1 as file, 0 as folder FROM file WHERE public='1'
    union all
    SELECT user, 0 as file, 1 as folder FROM folder WHERE public='1'

    ) group by user
  • Steffen Zerbe
    Steffen Zerbe    Premium Member
    The company name is only visible to registered members.
    Re^2: Select aus zwei verschiedenen Tabellen
    Peter Raschendorfer schrieb:

    Eine Tabelle mit einem Kennzeichen, ob es sich um ein File oder einen Folder handelt, wäre natürlich die einfachste Lösung. Aber es wird wahrscheinlich Gründe dafür geben, dass zwei Tabellen angelegt wurden....
    Wahrscheinlich sind noch Spalten vorhanden, die objektspezifisch (File / Folder) sind und daher eine Zusammenlegung verhindern. Könnte man trotzdem machen und die objektspezifischen Eigenschaften in eine Kindtabelle auslagern, dann wäre man zumindestens die Union für die erste Bestimmung los und könnte die spezifischen Daten über einen Join dazuholen. Sollte jede Objektart eine spezifische Erweiterungstabelle haben, kommt man wohl um zwei Selects oder doch wieder eine Union nicht drumrum. Wie auch immer, die Union ist hier das Stichwort.

    Gruß


    Steffen
  • Post visible to registered members
  • User photo
    Peter Raschendorfer
    (not a XING member)
    Re^3: Select aus zwei verschiedenen Tabellen
    Michael Steiger schrieb:
    Wie schaffst du mit einem UNION, dass Werte aus 2 SELECTS (count_files, count_folders) nachher in einer Zeile aufscheinen?
    Mit dem UNION kämen ja zwei Zeilen heraus, was der OP aber nicht wollte.

    Stimmt, deshalb habe ich ja auch geschrieben:
    wenn jeder User jeweils immer nur in einer der beiden Tabellen vorkommen kann geht das am einfachsten mit UNION.
  • Stefan Frech
    Stefan Frech
    The company name is only visible to registered members.
    Re: Select aus zwei verschiedenen Tabellen
    Vielen Dank für Eure Antworten

    Ich habe es befürchtet, dann muss ich entweder:
    - wohl oder übel auf MySQL 5 upgraden und meine Aplikation Requirements anpassen
    oder...
    - das Ganze mit zwei Queries lösen.

    Freundliche Grüsse, Stefan
  • User photo
    Frank Kalis
    (not a XING member)
    Re^2: Select aus zwei verschiedenen Tabellen
    Stefan Frech schrieb:

    Ich möchte alle "user" die in der Tabelle "file" oder "folder" mindestens ein Feld "public" auf den Wert '1' gesetzt haben, und zusätzlich jeweils die Anzahl der "public" Felder. Mit zwei Queries krieg ich das gut hin:
    SELECT user, count(*) FROM file WHERE public='1' GROUP BY 'user'; SELECT user, count(*) FROM folder WHERE public='1' GROUP BY 'user';
    Nun, kann ich das auch mit einer Query, sodass ich nachher das folgende Ergebnis hab?
     
    user count_files count_folders ============================
    Hans 27 8 Fritz 334 27 ...

    Ich würde zunächst einmal die Menge der eindeutigen User per UNION sammeln und dann LEFT JOINs über user auf file und folder Tabelle machen. Keine Ahnung, ob das in MySQL funktioniert, aber in SQL Server so etwas in dieser Richtung:

    IF OBJECT_ID('tempdb..#file') > 0
    DROP TABLE #file, #folder

    CREATE TABLE #file (
    [user] VARCHAR(20) NOT NULL default '',
    title VARCHAR(70) NOT NULL default '',
    [public] TINYINT default 0 not null
    );

    CREATE TABLE #folder (
    [user] VARCHAR(20) NOT NULL default '',
    title VARCHAR(70) NOT NULL default '',
    [public] TINYINT default 0 not null
    );

    INSERT INTO #file SELECT 'Meier', 'wasauchimmer1', 1
    UNION ALL SELECT 'Meier', 'wasauchimmer2', 1
    UNION ALL SELECT 'Meier', 'wasauchimmer3', 1
    UNION ALL SELECT 'Müller', 'wasauchimmer1', 0


    INSERT INTO #folder SELECT 'Müller', 'Müller1', 1
    UNION ALL SELECT 'Müller', 'Müller2', 0
    UNION ALL SELECT 'Müller', 'wasauchimmer', 0
    UNION ALL SELECT 'Meier', 'Meier1', 1

    SELECT usr, count_files, count_folders
    FROM
    (SELECT [user] AS usr
    FROM #file
    UNION
    SELECT [user]
    FROM #folder) AS t1
    LEFT JOIN
    (SELECT t1.[user], COUNT(*) count_files
    FROM #file t1
    WHERE [public] = 1
    GROUP BY t1.[user]) AS x
    ON t1.usr = x.[user]
    LEFT JOIN
    (SELECT t2.[user], COUNT(*) count_folders
    FROM #folder t2
    WHERE t2.[public] = 1
    GROUP BY t2.[user]) AS x2
    ON t1.usr = x2.[user]


    usr count_files count_folders
    -------------------- ----------- -------------
    Meier 3 1
    Müller NULL 1

    (2 row(s) affected)
    --
    Frank Kalis
    Microsoft SQL Server MVP
    Webmaster: http://www.insidesql.de
    This post was modified on 18 Sep 2007 at 01:58 pm.
  • User photo
    Peter Raschendorfer
    (not a XING member)
    Re^3: Select aus zwei verschiedenen Tabellen
    Frank Kalis schrieb:
    Ich würde zunächst einmal die Menge der eindeutigen User per UNION sammeln und dann LEFT JOINs über user auf file und folder Tabelle machen.
    Ein ziemlich umständlicher Weg um zum selben Ergebnis zu kommen wie mit dem von Lars Pohlmann geposteten Statement...