2012-03-28 41 views
5

Tôi đang tạo ứng dụng trong Symfony 1.4 và Doctrine 1.2 ORM. Tôi khá mới với học thuyết ORM và tôi đang bị treo cổ nhưng tôi không thể giải quyết được vấn đề này.Học thuyết Symfony Truy vấn để tính xếp hạng sau một nhóm theo truy vấn phụ

Tôi có một bảng điểm người dùng (mbScoreByGenre) trong đó một id người dùng có thể có nhiều bản ghi điểm số của người dùng cho một parent_genre. nghĩa là - nhiều người đến số nhiều

Mục tiêu của tôi là tìm thứ hạng của một người dùng cụ thể dựa trên điểm tích lũy của anh ấy cho một parent_genre_id và user_id đã cho. Thuật toán xếp hạng của tôi sử dụng truy vấn con và tôi đã gặp nhiều rắc rối khi xây dựng truy vấn học thuyết hoạt động.

Dưới đây là sơ đồ thuyết của tôi cho mbScoreByGenre

mbScoreByGenre: 
    actAs: 
    Timestampable: ~  
    columns: 

    id:     { type: integer, primary: true, autoincrement: true } 
    user_id:   { type: integer, notnull: true } 
    genre_id:   { type: integer, notnull: true } 
    parent_genre_id: { type: integer, notnull: true } 
    score:    { type: float, notnull: true, default: 0 } 

A. Trước tiên tôi đã cố gắng để làm một cái gì đó như thế này:

$q = Doctrine_Query::create() 
    ->select('((SELECT COUNT(1) AS num 
     FROM 
     (SELECT SUM(mbScoreByGenre.score) 
     WHERE SUM(mbScoreByGenre.score) > SUM(s.score) 
     AND mbScoreByGenre.parent_genre_id = '.$genre['parent_id'].' 
     AND s.parent_genre_id = '.$genre['parent_id'].' 
     GROUP BY mbScoreByGenre.user_id 
     ) + 1) AS rank') 
    ->from('mbScoreByGenre s') 
    ->where('s.user_id = ?', array($user_id)) 
    ->groupBy('s.user_id') 
    ->orderBy('rank'); 

but I got the following error Fatal error: Maximum function nesting level of '100' reached, aborting! in \lib\vendor\symfony-1.4.14\lib\plugins\sfDoctrinePlugin\lib\vendor\doctrine\Doctrine\Query\Tokenizer.php on line 303. I don't understand how to build the subquery so that it works.

B. Vì vậy, sau đó tôi đã thay đổi và cố gắng một cách tiếp cận khác nhau

$q = new Doctrine_RawSql(); 
$q ->addComponent('s', 'mbScoreByGenre') 
    ->select('COUNT({*}) AS {rank}') 
    ->from('(SELECT SUM(s.score) AS total_score 
     FROM mb_score_by_genre s 
     WHERE s.parent_genre_id = '.$genre['parent_id'].' 
     GROUP BY s.user_id) 
      ') 
    ->where('total_score >= (
     SELECT SUM(s.score) 
     FROM mb_score_by_genre s 
     WHERE s.parent_genre_id = '.$genre['parent_id'].' 
     AND s.user_id = '.$user_id.' 
     GROUP BY s.user_id 
    )'); 

Nhưng tôi đã nhận lỗi này: Tất cả các trường được chọn trong truy vấn Sql phải ở định dạng tableAlias.fieldName. Lý do tôi sử dụng Doctrine_RawSql là tôi đọc rằng doctrine 1.2 không hỗ trợ các truy vấn con trong From. Đối với phương pháp này, tôi không thể tìm ra cách tham chiếu cột "total_score" theo định dạng tableAlias.fieldName. Tôi có phải thêm một thành phần trống tham chiếu đến bảng truy vấn con được trả lại cho "total_score" không?

C. Cuối cùng tôi đã cố gắng chạy truy vấn con dưới dạng truy vấn học thuyết và tính toán thứ hạng bằng cách đếm các hàng đối tượng của giáo lý được trả về bởi truy vấn.

$q = Doctrine_Query::create() 
    ->select('SUM(s.score)') 
    ->from('mbScoreByGenre s') 
    ->where('s.parent_genre_id = ?', $genre['parent_id']) 
    ->andWhere('SUM(s.score) > (
     SELECT SUM(p.score) 
     FROM mbScoreByGenre p 
     WHERE p.parent_genre_id = '.$genre['parent_id'].' 
     AND p.user_id = '.$user_id.' 
     GROUP BY p.user_id 
    )') 
    ->groupBy('s.user_id'); 

    $result = $q->execute(); 

Nhưng nó mang lại cho tôi những lỗi:

SQLSTATE[HY000]: General error: 1111 Invalid use of group function. Is it because groupBy('s.user_id') and GROUP BY p.user_id, both p and s refer to the same model?

tôi đã thực hiện một tấn sục sạo trên web cho câu trả lời nhưng tôi dường như không thể tìm thấy câu trả lời cho bất kỳ của 3 phương pháp tiếp cận.

Mọi trợ giúp đều tuyệt vời. Cảm kích điều đó.

+0

51 điểm và không có phản ứng? Có điều gì tôi có thể làm để làm cho câu hỏi rõ ràng hơn không? Bất kì sự trợ giúp nào đều được đánh giá cao. – frankp221

Trả lời

2

Có thể, tôi không hiểu đầy đủ những gì bạn thực sự cần, nhưng bạn đã thử mệnh đề HAVING? Mệnh đề WHERE không hỗ trợ các hàm tổng hợp như SUM(). Tôi đã thử mã này và nó đã làm việc và trở về một số giá trị, nhưng tôi không thể nói chắc chắn nếu điều này là những gì bạn cần:

$q = Doctrine_Query::create() 
    ->select('count(*)') 
    ->from('mbScoreByGenre s') 
    ->where('s.parent_genre_id = ?', $genre['parent_id']) 
    ->having("SUM(s.score) > (
    SELECT SUM(p.score) 
    FROM mbScoreByGenre p 
    WHERE p.parent_genre_id = {$genre['parent_id']} 
     AND p.user_id = {$user_id})") 
->groupBy('s.user_id'); 

$result = $q->execute(array(), Doctrine::HYDRATE_SCALAR); 
var_dump($result); 

Nếu đây không phải là những gì bạn cần - cố gắng giải thích chính xác hơn.

+0

Cảm ơn rất nhiều starl1ng, vấn đề là WHERE không hỗ trợ chức năng tổng hợp. Tôi cũng đã phải đặt groupBy trước mệnh đề where. Bảng kết quả cung cấp cho tôi một danh sách tất cả các bản ghi phía trước user_id hiện tại. Để có được thứ hạng, tôi chỉ đếm các hàng và thêm 1. Cảm ơn một lần nữa. – frankp221

0

Bạn không được lồng truy vấn phụ vào nơi điều kiện (hoặc trong trường hợp của bạn) sử dụng sql thô. Thay vào đó, hãy sử dụng createSubquery() để nói rõ ràng về học thuyết về truy vấn phụ. Điều này cũng sẽ giúp bạn trong các tình huống phức tạp hơn trong đó học thuyết không thể xử lý các truy vấn sql nguyên lồng nhau sâu hơn nữa.Vì vậy, câu hỏi của bạn nên tìm một cái gì đó như thế này:

$q = Doctrine_Query::create() 
    ->select('count(*)') 
    ->from('mbScoreByGenre s') 
    ->where('s.parent_genre_id = ?', $genre['parent_id']) 
    ->groupBy('s.user_id') 
; 

$subquery = $q->createSubquery() 
    ->select("SUM(p.score)") 
    ->from("FROM mbScoreByGenre p") 
    ->where("p.parent_genre_id = ?", $genre['parent_id']) 
    ->andWhere("p.user_id = ?", $user_id) 
; 

$q->having("SUM(s.score) > (".$subquery->getDql().")"); 

Một ví dụ khác có thể được tìm thấy ở đây:

http://www.philipphoffmann.de/2012/08/taming-doctrine-subqueries/

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