2014-11-05 52 views
0

我需要一點建議。好還是壞? - PHP循環中的Doctrine DBAL查詢

該任務是從MySQL數據庫表中生成一些統計數據。我使用Doctrine DBAL類進行查詢。

所以我們在這裏兩個表(減少爲例):

USERS-表

 
user_id | user_name | user_gender | ... 
--------------------------------------- 
1234 | Klark Kent | 1   | ... 
2468 | Lex Luthor | 1   | ... 
3579 | Louis Lane | 2   | ... 
.... 


簽到桌

 
checkin_id | checkin_user_id | checkin_month | ... 
-------------------------------------------------- 
1   | 1234   | 1    | ... 
2   | 2468   | 1    | ... 
3   | 1234   | 1    | ... 
4   | 1234   | 2    | ... 
.... 


統計,結果應該是像這樣到底:

 
Month | All | Male | Female | Unique 
------------------------------------ 
Jan | 312 | 179 | 133 | 224 
Feb | 295 | 169 | 135 | 218 
Mar | 301 | 154 | 147 | 230 
.... 


所以基本上我就是這麼做的:

for ($i = 1; $i <= 12; $i++) {  
    $QB = $DB->createQueryBuilder(); 
    $STMT = $QB 
     ->select('c.checkin_id') 
     ->from(CHECKIN_TABLE, 'c') 
     ->innerJoin('c', USER_TABLE, 'u', 'c.checkin_user_id = u.user_id') 
     ->where('u.user_gender = 1') 
     ->andWhere('c.checkin_month = :month') 
     ->setParameter('month', (int)$i) 
     ->execute(); 
    ; 
    $stats[$i]['male'] = $STMT->rowCount(); 
    $QB = $DB->createQueryBuilder(); 
    $STMT = $QB 
     ->select('c.checkin_id') 
     ->from(CHECKIN_TABLE, 'c') 
     ->innerJoin('c', USER_TABLE, 'u', 'c.checkin_user_id = u.user_id') 
     ->where('u.user_gender = 2') 
     ->andWhere('c.checkin_month = :month') 
     ->setParameter('month', (int)$i) 
     ->execute(); 
    ; 
    $stats[$i]['female'] = $STMT->rowCount(); 
    $stats[$i]['all'] = $stats[$i]['male']+$stats[$i]['female']; 
    $QB = $DB->createQueryBuilder(); 
    $STMT = $QB 
     ->select('DISTINCT checkin_user_id') 
     ->from(CHECKIN_TABLE, 'c') 
     ->where('checkin_month = :month') 
     ->setParameter('month', (int)$i) 
     ->execute(); 
    ; 
    $stats[$i]['unique'] = $STMT->rowCount(); 
} 

正如你可以看到我在12次循環中運行3個查詢。由於查詢相對簡單,這可能是好的,但是如果可以做得更好,我會很樂意聽到您的意見。

也許選擇所有條目,然後做一個大量IF子句的WHILE-Fetch循環?

if (($row['checkin_month'] == 1) && ($row['user_gender'] == 1) $stats[1]['male']++; 
if (($row['checkin_month'] == 1) && ($row['user_gender'] == 2) $stats[1]['female']++; 
if (($row['checkin_month'] == 2) && ($row['user_gender'] == 1) $stats[2]['male']++; 
if (($row['checkin_month'] == 2) && ($row['user_gender'] == 2) $stats[2]['female']++; 


正如我們在這裏,一個問題。我讀過使用DISTINCT刪除重複的條目不是最佳做法,但我不知道如何才能做到這一點,否則。我已經閱讀了WHERE EXISTS的內容,但這不起作用,因爲我只是在這裏查詢單個表格的DISTINCT調用,我想。

如果您有任何提示或想法,請告訴我。 謝謝大家。

回答

0

幸運的是,我在閱讀和搜索了很多東西后,自己找到了一個解決方案。

因此,對於每個可能有類似任務的人員,這裏是如何使用單個查詢完成的。
(不過,我不知道如何使用該查詢生成器生成這一點,但它可以作爲的SQL語句。)

$SQL = 'SELECT 
     c.checkin_month, count(*) AS count, 
     count(DISTINCT c.checkin_member_id) AS uniq, 
     sum(case when u.user_gender = 1 then 1 else 0 end) AS male, 
     sum(case when u.user_gender = 2 then 1 else 0 end) AS female 
     FROM 
     '.CHECKIN_TABLE.' c, 
     '.USER_TABLE.' u 
     WHERE 
     c.checkin_user_id = u.user_id 
     GROUP BY 
     c.checkin_month'; 
$res = $DB->fetchAll($SQL); 


所以更少的代碼,更少的查詢,同樣的結果。