2011-04-20 12 views
5

मेरे पास निम्न तालिकाओं:संख्या:

post (id, title, content) etc 
author (id, username) etc 
author_vote (post_id, author_id, value) 

मूल्य एक tiny_int है कि या तो किया जा सकता है 1 या -1।

मैं प्रत्येक पद के लिए सकारात्मक और नकारात्मक वोटों की संख्या की गणना करना चाहते:

$posts = sql_select($link, "SELECT post.*, author.username 
          FROM post, author 
          AND author.id = post.author_id"); 

निम्नलिखित कोड क्यों काम नहीं करता है?

foreach ($posts as &$post) 
{ 
    $id = $post['id']; 
    $post['positive'] = (int)sql_select($link, "SELECT SUM(value) FROM author_vote WHERE post_id = $id 
              AND value = 1"); 
    $post['negative'] = (int)abs(sql_select($link, "SELECT SUM(value) FROM author_vote WHERE post_id = $id 
               AND value = -1")); 
} 

इसके अलावा डेटाबेस एकाधिक क्वेरी करने के लिए बिना यह करने के लिए किसी भी तरह से है:

array_walk($posts, function(&$post, $link){ 
    $post['positive'] = sql_select($link, "SELECT SUM(value) FROM author_vote WHERE post_id = $post['id'] 
              AND value = 1"); 

    $post['negative'] = abs(sql_select($link, "SELECT SUM(value) FROM author_vote WHERE post_id = $post['id'] 
              AND value = -1")); 
}); 

मैं भी निम्नलिखित की कोशिश की है, यह उस प्रत्येक पद के लिए एक ही हो सब वोट का कारण बनता है प्रत्येक पोस्ट के लिए समय? कुछ ऐसा कैसे होता है जो लगातार बदल रहा है [इस तरह] (मेम) कैश्ड हो?

+0

'एसक्यूएल क्या करता है _select' वापसी? क्या इस समारोह के लिए दस्तावेज है? – webbiedave

+0

आपके वर्तमान एसक्यूएल में आप एसयूएम का उपयोग कर रहे हैं जब वास्तव में आप COUNT का उपयोग कर सकते हैं जो तेजी से परिणाम देगा। –

+0

sql_select एक ऐसा फ़ंक्शन है जिसे मैंने स्वयं बनाया है, यदि कोई एसक्यूएल क्वेरी गलत है तो यह एक अपवाद फेंकता है (यानी यह चयन नहीं कर सकता) – jonnnnnnnnnie

उत्तर

5

आप एक ही क्वेरी में आपके गिनती कर सकता है:

Select Sum(Case When value < 0 Then 1 Else 0 End) As NegVotes 
    , Sum(Case When value > 0 Then 1 Else 0 End) As PosVotes 
From author_vote 
Where post_id = ... 

आप पोस्ट प्रति सकारात्मक और नकारात्मक वोट चाहते हैं:

Select post_id 
    , Sum(Case When value < 0 Then 1 Else 0 End) As NegVotes 
    , Sum(Case When value > 0 Then 1 Else 0 End) As PosVotes 
From author_vote 
Group By post_id 

आप अपने पहले क्वेरी गठबंधन करना चाहता है तो और दूसरी क्वेरी आप प्राप्त कर सकते हैं:

Select post.... 
    , author.username 
    , Coalesce(post_count.NegVotes,0) As NegVotes 
    , Coalesce(post_count.PosVotes,0) As PosVotes 
From post 
    Join author 
     On author.id = post.author_id 
    Left Join (
       Select post_id 
        , Sum(Case When value < 0 Then 1 Else 0 End) As NegVotes 
        , Sum(Case When value > 0 Then 1 Else 0 End) As PosVotes 
       From author_vote 
       Group By post_id 
       ) As post_count 
     On post_count.post_id = post.post_id 
+0

आप इसे पहली क्वेरी के साथ कैसे जोड़ेंगे? तो मैं प्रत्येक पोस्ट से जुड़े सभी पदों और वोटों का चयन कर सकता हूं। – jonnnnnnnnnie

+0

@jonnnnnnnnnie - आप बस इस क्वेरी को व्युत्पन्न तालिका में भर देंगे। मैंने चित्रण के लिए अपना जवाब विस्तारित किया है। – Thomas

0

मुझे आपके द्वारा उपयोग किए जाने वाले फ़ंक्शन sql_select() नहीं मिल रहे हैं, लेकिन sum() की कोशिश करने के बजाय आप अपने SQL में count(*) का उपयोग बंद कर सकते हैं। आपको केवल पंक्तियों की गिनती करने की आवश्यकता है, जो मानों की तुलना नहीं करते हैं। तुम भी एक छोटे से अधिक सजावटी हो और द्वारा एक ग्रुप इस्तेमाल कर सकते हैं:

SELECT value, count(value) AS value_count FROM author_vote WHERE post_id = $id GROUP BY value 

यह प्रत्येक अनन्य मान के लिए एक पंक्ति वापस आ जाएगी। लौटाई गई प्रत्येक पंक्ति अद्वितीय मूल्य और उस मान का उपयोग करके पंक्तियों की गणना की रिपोर्ट करेगी।