对于SQL查询中的循环

时间:2014-03-12 03:43:09

标签: php mysql sql postgresql

我有一个名为watersourcetype的表,由水类型组成。

link:watersourcetype TABLE

另一个表health_and_sanitation由家庭号组成。和watersource_id 我有这个问题:

SELECT h.purok_number,
    SUM(CASE WHEN hs.watersystem = 'Community water system-own' THEN 1 ELSE 0 END) AS a,
    SUM(CASE WHEN hs.watersystem = 'Community water system-shared' THEN 1 ELSE 0 END) AS b,
    SUM(CASE WHEN hs.watersystem = 'Deep well-own' THEN 1 ELSE 0 END) AS c,
    SUM(CASE WHEN hs.watersystem = 'Deep well-shared' THEN 1 ELSE 0 END) AS d,
    SUM(CASE WHEN hs.watersystem = 'Artesian well-own' THEN 1 ELSE 0 END) AS e,
    SUM(CASE WHEN hs.watersystem = 'Artesian well-shared' THEN 1 ELSE 0 END) AS f,
    SUM(CASE WHEN hs.watersystem = 'Dug/shallow well-own' THEN 1 ELSE 0 END) AS g,
    SUM(CASE WHEN hs.watersystem = 'Dug/shallow well-shared' THEN 1 ELSE 0 END) AS h,
    SUM(CASE WHEN hs.watersystem = 'River, stream, lake, spring, bodies of water' THEN 1 ELSE 0 END) AS i,
    SUM(CASE WHEN hs.watersystem = 'Bottled water' THEN 1 ELSE 0 END) AS j,
    SUM(CASE WHEN hs.watersystem = 'Tanker truck/Peddler' THEN 1 ELSE 0 END) AS k
FROM health_and_sanitation AS hs, house_hold AS h, f_member as f 
WHERE
     h.brgy_name='$brgy_name' AND 
     h.hh_number=hs.hh_number AND 
     h.hh_number=f.hh_number AND
     f.is_household='HOUSEHOLD' AND 
     EXTRACT(YEAR FROM f.reg_date) BETWEEN '$sel_year' AND '$sel_year' 
group by h.purok_number 
order by h.purok_number

我想要的是在sql查询上面放置一个for循环,因为表watersourcetype是动态的,很快就会将另一个数据添加到watersourcetype中,所以我不必在我的case语句中定义上面的查询水系统。查询应如下所示:

$qry = pg_query("select cwatertype from tbl_watersourcetype");

SQL:

SELECT h.purok_number, 
           // is this possible ? putting a while loop or forloop inside a query in PHP ?
          while($row = pg_fetch_array($qry)) 
          {
           SUM(CASE WHEN hs.watersystem = '$row['cwatertype']' THEN 1 ELSE 0 END) AS a 
          }
FROM health_and_sanitation AS hs, house_hold AS h, f_member as f 
WHERE
    h.brgy_name='$brgy_name' AND 
    h.hh_number=hs.hh_number AND 
    h.hh_number=f.hh_number AND
    f.is_household='HOUSEHOLD' AND 
    EXTRACT(YEAR FROM f.reg_date) BETWEEN '$sel_year' AND '$sel_year' 
group by h.purok_number 
order by h.purok_number

可能吗?

2 个答案:

答案 0 :(得分:2)

如果我正确理解您的查询,您将尝试检索每个家庭的水源类型数量,每个家庭返回一条记录。如果确实如此,您需要使用crosstab()扩展程序中的tablefunc函数。

但是,如果您可以使用多个行来显示每个家庭每个水源类型的来源数量,那么您可以简单而有效地使用COUNT()语句中的SELECT聚合(使用某些体面的格式化易读性):

SELECT h.purok_number, hs.watersystem, COUNT(hs.watersystem) AS num
   FROM health_and_sanitation AS hs,
        house_hold AS h,
        f_member AS f
   WHERE h.brgy_name='$brgy_name'
     AND h.hh_number=hs.hh_number
     AND h.hh_number=f.hh_number
     AND f.is_household='HOUSEHOLD'
     AND EXTRACT(YEAR FROM f.reg_date) BETWEEN '$sel_year' AND '$sel_year'
   GROUP BY h.purok_number, hs.watersystem
   ORDER BY h.purok_number;

此外,我假设你的health_and_sanitation表是watersourcetype表上的一个视图;否则你在两个表中复制数据,这通常是一个大嘘声。鉴于您的额外水源类型问题,您可能想看看您的数据库设计是否在3NF

干杯, 帕特里克

答案 1 :(得分:0)

这是关于如何在SELECT语句中放置循环的示例:

$qry_6_12 .= "  SELECT count(ncropfarmingreasonid) as counted , " ;

     for($i=2;$i<=$count_row;$i++) // loop the number of rows and used $i as ncropfarmingreasonid 
          {           
            if(($count_row-$i)==0)
              {
                 $qry_6_12 .= "SUM(CASE WHEN ncropfarmingreasonid = ".$i." THEN 1
                 ELSE 0 END) a".$i."";
              }  
            else 
              {
                 $qry_6_12 .= "SUM(CASE WHEN ncropfarmingreasonid = ".$i." THEN 1  
                 ELSE 0 END) a".$i.",";                                  
              }        
          }
      $qry_6_12 .= " FROM tbl_climatechange as c, tbl_household as h, tbl_barangay as b where h.chholdnumber=c.chholdnumber and b.cbrgycode=h.cbrgycode and b.cbrgyname = 'AMPAYON' ";
      $query_6_12 = pg_query($qry_6_12);