2009-12-29 39 views
41

Có cách nào để chỉ định trường truy vấn cha mẹ từ bên trong truy vấn phụ trong mySQL không?Cách chỉ định trường truy vấn cha mẹ từ trong truy vấn phụ trong mySQL?

Ví dụ:
Tôi đã viết chương trình loại Bảng thông báo cơ bản bằng PHP.

Trong cơ sở dữ liệu, mỗi bài đăng chứa: id (PK) và parent_id (id của bài đăng gốc). Nếu bài đăng đó là chính nó, thì parent_id của nó được đặt thành 0.

Tôi đang cố gắng viết truy vấn mySQL sẽ tìm thấy mọi bài đăng gốc và số lượng con mà cha mẹ có.

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

Phần khôn lanh là các id đầu tiên không biết rằng nó nên được đề cập đến thứ hai id đó là bên ngoài của subquery. Tôi biết rằng tôi có thể làm SELECT id AS id_tmp và sau đó tham khảo nó bên trong truy vấn phụ, nhưng sau đó nếu tôi muốn cũng trả về id và giữ "id" như tên cột, sau đó tôi phải làm một truy vấn trả về 2 cột có cùng dữ liệu (có vẻ lộn xộn với tôi)

$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"; 

Cách lộn xộn hoạt động tốt, nhưng tôi cảm thấy có cơ hội học hỏi điều gì đó ở đây vì vậy tôi nghĩ mình sẽ đăng câu hỏi.

Trả lời

60

Làm thế nào về:

$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"; 

hoặc nếu bạn đặt một bí danh trên p1.id, bạn có thể nói:

$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"; 
+0

nếu tôi đã sử dụng bí danh cho p1.id thì sao? –

+0

Điều đó có nghĩa là gì? "lấy bí danh cho"? – Don

+0

Nếu tôi đã thực hiện bí danh như: "SELECT p1.id là MYID," thì truy vấn sẽ là gì? –

2

Cho bảng tên duy nhất:

$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"; 
4

Bạn có thể thử một cái gì đó như thế này

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 

Để quay trở lại ví dụ của bạn, sử dụng bí danh của bảng chính trong tiểu chọn

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

Cú pháp sau đây làm việc tại Oracle. Bạn có thể kiểm tra nếu các công trình tương tự trong MYSQL không? Nó được gọi là truy vấn phụ vô hướng trong Oracle.

Bạn chỉ cần đặt bí danh hai bảng khác nhau để phân biệt giữa hai bảng nếu bạn đang sử dụng cùng một bảng hai lần.

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

Cảm ơn Don. Tôi đã có một truy vấn lồng nhau như được hiển thị bên dưới và một mệnh đề WHERE trong nó không thể xác định bí danh v1. Đây là mã mà không hoạt động:

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 */ 
); 

Vì vậy, tôi chỉ cần thêm bí danh v1 lại bên trong JOIN. Mà làm cho nó hoạt động.

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 */ 
); 

Hy vọng điều này sẽ hữu ích cho người khác.

Các vấn đề liên quan