通过赋值"返回所有行包括不存在的行 - "值

时间:2014-05-26 01:28:09

标签: php sql postgresql

我有一张桌子" AA"下面。由此代码创建的表结构

CREATE TABLE "AA" (
height character varying DEFAULT '-'::character varying,
class character varying NOT NULL,
gender character varying NOT NULL,
origin character varying NOT NULL
);

然后数据是

Height  class   gender  origin
162        1      m      a
169        1      f      a
172        1      m      b
169        2      f      b
171        2      f      a

然后我想获得包含类(1,3)和性别(m)以及原点(a,b)的组合的查询 如果期望的结果看起来像这样,我怎样才能实现它

Height  class   gender  origin
162       1       m       a
172       1       m       b
-         3       m       a
-         3       m       b

我试过

Select COALESCE(height), class, gender, origin 
FROM AA 
WHERE class in ('1','3') and gender in ('m') and origin in ('a','b')

但它只返回第二个表格的两行。

然后我尝试这个 //在php中

<?php
    $class = array('1', '3');
    $gender = array('m');
    $origin = array('a', 'b');

    for ($i = 0; $i < count($class); $i++) {
        for ($j = 0; $j < count($gender); $j++) {
            for ($k = 0; $k < count($origin); $k++) {
                $query = 'select * from "AA" where ' .
                        " class = '" . $class[$i] .
                        "' and gender = '" . $gender[$j] .
                        "' and origin = '" . $origin[$k] . "' ";
                $result = pg_query($query) or die('Query failed: ' . pg_last_error());
                $row = pg_fetch_assoc($result);
                if (!$row) {
                    $row['height'] = "-";
                    $row['class'] = $class[$i];
                    $row['gender'] = $gender[$j];
                    $row['origin'] = $origin[$k];
                }
                if (is_null($row['height'])) {
                    $row['height'] = '-';
                }
                print_r($row);
            }
        }
    }
    ?>

一个。是否有任何有效的技术来检查零行结果并分配&#34; - &#34;特定颜色的价值? 湾在php或sql中有更好的迭代,如果字段大于3(扩展),如何进行动态迭代?

问候。

2 个答案:

答案 0 :(得分:0)

最重要的是让所有列表都正确无误。第二个是将'-'放在正确的位置。您可以使用cross join执行第一部分,然后明智地使用cast()left outer join执行第二部分:

select (case when t.height is null then '-' else cast(height as varchar(255)) end) as height,
       c.theclass. g.gender, o.origin
from (select 1 as theclass union all select 2) c cross join
     (select 'm' as gender) g cross join
     (select 'a' as origin union all select 'b') o left outer join
     table t
     on t.class = c.theclass and t.gender = g.gender  and t.origin = o.origin;

编辑:

如果class是一个字符,请尝试:

select (case when t.height is null then '-' else cast(height as varchar(255)) end) as height,
       c.class. g.gender, o.origin
from (select '1' as class union all select '2') c cross join
     (select 'm' as gender) g cross join
     (select 'a' as origin union all select 'b') o left outer join
     table t
     on t.class = c.class and t.gender = g.gender  and t.origin = o.origin;

答案 1 :(得分:0)

1将sql中的所有现有值读入由类,性别和关联索引的关联数组中。

2迭代所有可能的组合,然后使用isset来检测&amp;填补缺失的组合。

$query = "Select height, class, gender, origin FROM AA WHERE class in ('1','3') and gender in ('m') and origin in ('a','b')";

$result = pg_query($query) or die(pg_last_error());

while($row = pg_fetch_assoc($result)) {
    //read in all existing values and index by class, gender, origin combo
    $key = $row['class'] . $row['gender'] . $row['origin'];
    $rows[$key] = $row;
}

$classes = array('1', '3');
$genders = array('m');
$origins = array('a', 'b');

//iterate over all possible combinations
foreach($classes as $class) {
    foreach($genders as $gender) {
        foreach($origins as $origin) {
            $key = $class . $gender . $origin;
            if(!isset($rows[$key])) { 
                //we're missing a value for the given class/origin/gender combo, so fill it in
                $rows[$key] = array(
                    'height' => '-',
                    'class' => $class,
                    'gender' => $gender,
                    'origin' => $origin,
                );
            }
        }
    }
}

print_r($rows);