从数据表和透视查找表构造嵌套的PHP关联数组

时间:2016-06-14 15:36:10

标签: php postgresql

我有以下人口普查数据表:

| district | hc01_vc03 | hc02_vc03 | hc03_vc03 | hc04_vc03 |
|----------|-----------|-----------|-----------|-----------|
|  01A     |  16681    |    209    |   16681   |   (x)     |
|  01B     |  15844    |    256    |   15844   |   (x)     |
|  02A     |  12514    |    283    |   15214   |   (x)     |
|  02B     |  16105    |    236    |   16105   |   (x)     |

我有以下“查找”表:

|   NAME    | DESCRIPTION                                                      |
|-----------|------------------------------------------------------------------|
| hc01_vc03 | "Estimate; HOUSEHOLDS BY TYPE - Total households"                |
| hc02_vc03 | "Margin of Error; HOUSEHOLDS BY TYPE - Total households"         |
| hc03_vc03 | "Percent; HOUSEHOLDS BY TYPE - Total households"                 |
| hc04_vc03 | "Percent Margin of Error; HOUSEHOLDS BY TYPE - Total households" |

我需要返回以下JSON对象:

 {"Census":[
    {"geographicProfile":{
       "district":"01A",
       "hc01_vc03":[16681, 'Estimate; HOUSEHOLDS BY TYPE - Total households']
       "hc02_vc03":[209, 'Margin of Error; HOUSEHOLDS BY TYPE - Total households']
       "hc03_vc03":[16681, 'Percent; HOUSEHOLDS BY TYPE - Total households']
       "hc04_vc03":['(x)', 'Percent Margin of Error; HOUSEHOLDS BY TYPE - Total households']
    }},
    {""geographicProfile":{
       "district":"01B",
       "hc01_vc03":[15844, 'Estimate; HOUSEHOLDS BY TYPE - Total households']
       "hc02_vc03":[256, 'Margin of Error; HOUSEHOLDS BY TYPE - Total households']
       "hc03_vc03":[15844, 'Percent; HOUSEHOLDS BY TYPE - Total households']
       "hc04_vc03":['(x)', 'Percent Margin of Error; HOUSEHOLDS BY TYPE - Total households']
    }}
    {etc},{etc}
]}

排除普通Select...From...我可以使用这个基本循环将每个表查询作为JSON返回:

$acsjson = array('Census'  => array());
while ($row = $rs->fetch(PDO::FETCH_ASSOC)) {
    $properties = $row;
    $feature = array(
        'geographicProfile' => $properties
    );
    array_push($acsjson['Census'], $feature);
}

echo json_encode($acsjson, JSON_NUMERIC_CHECK);

分别返回每个表JSON对象,数据和查找表之间没有任何连接。

但是我正在努力将“hc0X_vc03”变成一个数组,其中包含“查询表”查询description值到该数组中。我想我需要转动查找表。任何人都可以帮助构造JSON对象吗?

这是my question from yesterday

的扩展/修订版

我会对SQL或PHP解决方案感兴趣。

1 个答案:

答案 0 :(得分:1)

我在这里看到的问题是你的查找键是列名,很难想到如何加入它们。 但是,您只需要将所有查找描述作为一行连接到 ContentProvider () Construct a ContentProvider instance. Content providers must be declared in the manifest, accessed with ContentResolver, and created automatically by the system, so applications usually do not create ContentProvider instances directly. At construction time, the object is uninitialized, and most fields and methods are unavailable. Subclasses should initialize themselves in onCreate(), not the constructor. Content providers are created on the application main thread at application launch time. The constructor must not perform lengthy operations, or application startup will be delayed. 表的每一行。

步骤(从下到上)

  • 使用census data聚合旋转查找表。透视查找表只有一行。可以通过tablefunc扩展名来使用交叉表功能。
  • MAX()表交叉加入。
  • 使用json functions为每一行组装一个json对象。
  • 使用json aggregation汇编所有行的json数组。
  • 将最终密钥添加到json对象。

这是查询。

census data

PHP处理

如果你想在php代码中进行json汇编,请删除所有涉及json函数的select。

-- add 'Census' Key to aggregated json
SELECT jsonb_build_object('Census', agg_data) final_json FROM
(
  -- assemble json array
  SELECT jsonb_agg(json_data) agg_data FROM
  (
    -- Assemble json object with each row
    SELECT 
      jsonb_build_object(
        'geographicProfile', jsonb_build_object(
          'district', district, 
          'hc01_vc03', jsonb_build_array(hc01_vc03, hc01_vc03_lu), 
          'hc02_vc03', jsonb_build_array(hc02_vc03, hc02_vc03_lu), 
          'hc03_vc03', jsonb_build_array(hc03_vc03, hc03_vc03_lu), 
          'hc04_vc03', jsonb_build_array(hc04_vc03, hc04_vc03_lu)
    )
  ) json_data
  FROM ( 
    -- Cross Join census data with pivoted lookup table
    SELECT 
      district,
      a.hc01_vc03, b.hc01_vc03 hc01_vc03_lu,
      a.hc02_vc03, b.hc02_vc03 hc02_vc03_lu,
      a.hc03_vc03, b.hc03_vc03 hc03_vc03_lu,
      a.hc04_vc03, b.hc04_vc03 hc04_vc03_lu
    FROM
      public.census_data a, 
      (
      -- Pivot lookup table. Put all values in only one row with keys as column names. Could use tablefunc extension here.
      SELECT 
        MAX (CASE WHEN name = 'hc01_vc03' then description END) hc01_vc03,
        MAX (CASE WHEN name = 'hc02_vc03' then description END) hc02_vc03,
        MAX (CASE WHEN name = 'hc03_vc03' then description END) hc03_vc03,
        MAX (CASE WHEN name = 'hc04_vc03' then description END) hc04_vc03 
      FROM
        public.lookup
      ) b
    ) c
  ) d
) e

现在,您已经拥有了每行所需的所有信息,以便在PHP循环中创建json。

交叉表功能

需要安装

-- Cross Join census data with pivoted lookup table SELECT district, a.hc01_vc03, b.hc01_vc03 hc01_vc03_lu, a.hc02_vc03, b.hc02_vc03 hc02_vc03_lu, a.hc03_vc03, b.hc03_vc03 hc03_vc03_lu, a.hc04_vc03, b.hc04_vc03 hc04_vc03_lu FROM public.census_data a, ( -- Pivot lookup table. Put all values in only one row with keys as column names. Could use tablefunc extension here. SELECT MAX (CASE WHEN name = 'hc01_vc03' then description END) hc01_vc03, MAX (CASE WHEN name = 'hc02_vc03' then description END) hc02_vc03, MAX (CASE WHEN name = 'hc03_vc03' then description END) hc03_vc03, MAX (CASE WHEN name = 'hc04_vc03' then description END) hc04_vc03 FROM public.lookup ) b 扩展名。 使用此查询而不是透视查找选择。

Tablefunc

<强>的CTE

CTE更具可读性。

以下是查询的CTE版本。

SELECT * 
FROM public.crosstab( 'select ''lu1''::text, * from public.lookup' )
AS ct(lookup_name text,
      hc01_vc03 text, hc02_vc03 text,
      hc03_vc03 text, hc04_vc03 text)