it-swarm.com.de

Wie kann ich das übergeordnete Abfragefeld in einer Unterabfrage in mySQL angeben?

Gibt es eine Möglichkeit, das übergeordnete Abfragefeld in einer Unterabfrage in mySQL anzugeben?

Zum Beispiel:
Ich habe ein einfaches Bulletin-Board-Programm in PHP geschrieben.

In der Datenbank enthält jeder Beitrag: id (PK) und parent_id (die ID des übergeordneten Beitrags). Wenn der Beitrag selbst ein Elternteil ist, wird seine Eltern-ID auf 0 gesetzt.

Ich versuche, eine MySQL-Abfrage zu schreiben, die jeden übergeordneten Beitrag und die Anzahl der untergeordneten Elemente des übergeordneten Elements findet.

$query = "SELECT id, (
      SELECT COUNT(1) 
      FROM post_table 
      WHERE parent_id = id
) as num_children
FROM post_table
WHERE parent_id = 0";

Der schwierige Teil ist, dass der erste id nicht weiß, dass er sich auf den zweiten id beziehen sollte, der sich außerhalb der Unterabfrage befindet. Ich weiß, dass ich SELECT id AS id_tmp ausführen kann und dann in der Unterabfrage darauf verweisen kann. Wenn ich jedoch auch die id zurückgeben und "id" als Spaltennamen beibehalten möchte, muss ich eine Abfrage ausführen, die zurückgibt mir 2 Spalten mit den gleichen Daten (was mir unordentlich erscheint)

$query = "SELECT id, id AS id_tmp, 
            (SELECT COUNT(1)
            FROM post_table
            WHERE parent_id = id_tmp) as num_children
         FROM post_table
         WHERE parent_id = 0";

Der unordentliche Weg funktioniert gut, aber ich habe die Gelegenheit, hier etwas zu lernen, also dachte ich, ich würde die Frage posten.

46
justinl

Wie wäre es mit:

$query = "SELECT p1.id, 
                 (SELECT COUNT(1) 
                    FROM post_table p2 
                   WHERE p2.parent_id = p1.id) as num_children
            FROM post_table p1
           WHERE p1.parent_id = 0";

oder wenn Sie einen Alias ​​auf die p1.id setzen, könnten Sie sagen:

$query = "SELECT p1.id as p1_id, 
                 (SELECT COUNT(1) 
                    FROM post_table p2 
                   WHERE p2.parent_id = p1.id) as num_children
            FROM post_table p1
           WHERE p1.parent_id = 0";
67
Don

Sie könnten so etwas versuchen

SELECT  pt.id,
        CountTable.Cnt
FROM    post_table pt LEFT JOIN
        (
            SELECT  parent_id,
                    COUNT(1) Cnt
            FROM    post_table
            WHERE   parent_id <> 0
            GROUP BY parent_id
        ) CountTable ON pt.id = CountTable.parent_id
WHERE   pt.parent_id = 0

Um wieder zu Ihrem Beispiel zu gelangen, verwenden Sie die Option alias der Haupttabelle in der Unterauswahl

SELECT  pt.id,
        (SELECT COUNT(1) FROM post_table WHERE parent_id = pt.id) 
FROM    post_table pt
WHERE   pt.parent_id = 0
4
Adriaan Stander

Geben Sie den Tabellen eindeutige Namen:

$query = "SELECT a.id, (SELECT COUNT(1) FROM post_table b WHERE parent_id = a.id) as num_children FROM post_table a WHERE a.parent_id = 0";
2
Tatu Ulmanen

Die folgende Syntax funktioniert in Oracle. Können Sie testen, ob das gleiche auch in MYSQL funktioniert? In Oracle wird dies als skalare Unterabfrage bezeichnet.

Sie müssen lediglich die beiden Tabellen unterschiedlich aliasieren, um zwischen ihnen zu unterscheiden, wenn Sie dieselbe Tabelle zweimal verwenden.

sql> select empno,
  2         (select dname from dept where deptno = emp.deptno) dname
  3    from emp 
  4    where empno = 7369;

     EMPNO DNAME
---------- --------------
      7369 RESEARCH

sql> select parent.empno,
  2         (select mgr from emp where empno = parent.empno) mgr
  3    from emp parent
  4    where empno = 7876;

     EMPNO        MGR
---------- ----------
      7876       7788
0

Danke, Don. Ich hatte eine verschachtelte Abfrage (siehe unten) und eine WHERE-Klausel konnte den Alias ​​v1 nicht ermitteln. Hier ist der Code, der nicht funktioniert:

Select 
    teamid,
    teamname
FROM
    team as t1
INNER JOIN (
    SELECT 
        venue_id, 
        venue_scores, 
        venue_name 
    FROM venue 
    WHERE venue_scores = (
        SELECT 
            MAX(venue_scores) 
        FROM venue as v2 
        WHERE v2.venue_id = v1.venue_id      /* this where clause wasn't working */
    ) as v1    /* v1 alias already present here */
);

Also habe ich gerade den Alias ​​v1 wieder in die JOIN eingefügt. Was hat funktioniert?.

Select 
    teamid,
    teamname
FROM
    team as t1
INNER JOIN (
    SELECT 
        venue_id, 
        venue_scores, 
        venue_name 
    FROM venue as v1              /* added alias v1 here again */
    WHERE venue_scores = (
        SELECT 
            MAX(venue_scores) 
        FROM venue as v2 
        WHERE v2.venue_id = v1.venue_id   /* Now this works!! */
    ) as v1     /* v1 alias already present here */
);

Hoffe, das wird für jemanden hilfreich sein.

0
Mr_Green