2013-04-16 4 views
1

'통계'테이블에 값의로드를 추가하는 쿼리가 있습니다. 쿼리가 실행되면 하위 쿼리의 테이블을 채울 값을 선택합니다. 나는 이것이 더 효율적으로 만들 수 있는지 또는 내가 정말로 잘못된 것을하고 있는지 궁금해하고 있었다. ID PHP에서 추가됩니다 (가)MySQL 하위 쿼리 효율성

UPDATE mediastats SET 
    mediastats_members = (SELECT count(*) FROM status WHERE status_media_id = :id), 
    mediastats_avscore = (SELECT AVG(status_rating) FROM status WHERE status_media_id = :id), 
    mediastats_done = (SELECT count(*) FROM status WHERE status_status = 'done' AND status_media_id = :id), 
    mediastats_doing = (SELECT count(*) FROM status WHERE status_status = 'doing' AND status_media_id = :id), 
    mediastats_redoing = (SELECT count(*) FROM status WHERE status_status = 'redoing' AND status_media_id = :id), 
    mediastats_dropped = (SELECT count(*) FROM status WHERE status_status = 'dropped' AND status_media_id = :id), 
    mediastats_wantto = (SELECT count(*) FROM status WHERE status_status = 'wantto' AND status_media_id = :id), 
    mediastats_wont = (SELECT count(*) FROM status WHERE status_status = 'wont' AND status_media_id = :id), 
    mediastats_stalled = (SELECT count(*) FROM status WHERE status_status = 'stalled' AND status_media_id = :id), 
    mediastats_rating_1 = (SELECT count(*) FROM status WHERE status_rating = 1 AND status_media_id = :id), 
    mediastats_rating_2 = (SELECT count(*) FROM status WHERE status_rating = 2 AND status_media_id = :id), 
    mediastats_rating_3 = (SELECT count(*) FROM status WHERE status_rating = 3 AND status_media_id = :id), 
    mediastats_rating_4 = (SELECT count(*) FROM status WHERE status_rating = 4 AND status_media_id = :id), 
    mediastats_rating_5 = (SELECT count(*) FROM status WHERE status_rating = 5 AND status_media_id = :id), 
    mediastats_rating_6 = (SELECT count(*) FROM status WHERE status_rating = 6 AND status_media_id = :id), 
    mediastats_rating_7 = (SELECT count(*) FROM status WHERE status_rating = 7 AND status_media_id = :id), 
    mediastats_rating_8 = (SELECT count(*) FROM status WHERE status_rating = 8 AND status_media_id = :id), 
    mediastats_rating_9 = (SELECT count(*) FROM status WHERE status_rating = 9 AND status_media_id = :id), 
    mediastats_rating_10 = (SELECT count(*) FROM status WHERE status_rating = 10 AND status_media_id = :id) 
    WHERE mediastats_media_id = :id 

: 그래서 어떤 도움이 여기에 :)

좋은 것 쿼리는 MySQL의에 익숙한 아닙니다. 여기

답변

2

내가 PDO와 PHP에서 그것을 할 거라고 방법은 다음과 같습니다

$sql = " 
    SELECT 
    COUNT(*) AS mediastats_members, 
    AVG(status_rating) AS mediastats_avscore, 
    SUM(status_status = 'done') AS mediastats_done, 
    SUM(status_status = 'doing') AS mediastats_doing, 
    SUM(status_status = 'redoing') AS mediastats_redoing, 
    SUM(status_status = 'dropped') AS mediastats_dropped, 
    SUM(status_status = 'wantto') AS mediastats_wantto, 
    SUM(status_status = 'wont') AS mediastats_wont, 
    SUM(status_status = 'stalled') AS mediastats_stalled, 
    SUM(status_rating = 1) AS mediastats_rating_1, 
    SUM(status_rating = 2) AS mediastats_rating_2, 
    SUM(status_rating = 3) AS mediastats_rating_3, 
    SUM(status_rating = 4) AS mediastats_rating_4, 
    SUM(status_rating = 5) AS mediastats_rating_5, 
    SUM(status_rating = 6) AS mediastats_rating_6, 
    SUM(status_rating = 7) AS mediastats_rating_7, 
    SUM(status_rating = 8) AS mediastats_rating_8, 
    SUM(status_rating = 9) AS mediastats_rating_9, 
    SUM(status_rating = 10) AS mediastats_rating_10 
    FROM status 
    WHERE status_media_id = :id"; 
$stmt = $pdo->prepare($sql); 
$stmt->execute(array("id"=>$id)); 
$params = $stmt->fetch(PDO::FETCH_ASSOC); 

대신 각 계수에 대해 별도의 하위 쿼리를 사용하는 테이블의 한 번에 모든 집계를 계산 이쪽으로.

부울 표현식의 SUM()은 표현식이 참인 COUNT()와 같습니다. 이는 MySQL 부울식이 항상 0 또는 1을 반환하고 0과 1의 SUM이 1의 COUNT와 같기 때문입니다.

그런 다음 당신은 UPDATE 문에 매개 변수 배열과 위의 쿼리의 결과를 사용할 수 있습니다

$sql = " 
    UPDATE mediastats SET 
     mediastats_members = :mediastats_members, 
     mediastats_avscore = :mediastats_avscore, 
     mediastats_done = :mediastats_done, 
     mediastats_doing = :mediastats_doing, 
     mediastats_redoing = :mediastats_redoing, 
     mediastats_dropped = :mediastats_dropped, 
     mediastats_wantto = :mediastats_wantto, 
     mediastats_wont = :mediastats_wont, 
     mediastats_stalled = :mediastats_stalled, 
     mediastats_rating_1 = :mediastats_rating_1, 
     mediastats_rating_2 = :mediastats_rating_2, 
     mediastats_rating_3 = :mediastats_rating_3, 
     mediastats_rating_4 = :mediastats_rating_4, 
     mediastats_rating_5 = :mediastats_rating_5, 
     mediastats_rating_6 = :mediastats_rating_6, 
     mediastats_rating_7 = :mediastats_rating_7, 
     mediastats_rating_8 = :mediastats_rating_8, 
     mediastats_rating_9 = :mediastats_rating_9, 
     mediastats_rating_10 = :mediastats_rating_10 
    WHERE mediastats_media_id = :id"; 

$stmt = $pdo->prepare($sql); 
$params["id"] = $id; 
$stmt->execute($params); 

는 PHP 5.3.4 이후, PDO는 최고의 :없이 매개 변수 배열 키를 받아들입니다. 쿼리에서 매개 변수 자리 표시자를 선언 할 때는 콜론이 필요하지만 execute()에 제공 한 값 배열에는 필요하지 않습니다.

+0

감사합니다. :) 원본보다이 방법의 장점은 무엇입니까? – Humphrey

+1

장점은 테이블을 한 번 통과 할 때 모든 카운트를 계산한다는 것입니다. –

1
UPDATE (
     SELECT status_media_id, 
       COUNT(*) AS cnt, AVG(status_rating) AS avg_rating, 
       SUM(status_status = 'done') AS cnt_done, 
       ... 
     FROM status 
     WHERE status_media_id = :id 
     ) s 
JOIN mediastats ms 
ON  ms.mediastats_media_id = s.status_media_id 
SET  ms.mediastats_members = cnt, 
     ms.mediastats_avscore = avg_rating, 
     ms.mediastats_done = cnt_done, 
     ...