从Javascript中过滤掉PostgreSQL查询结果中的唯一数据

时间:2015-06-03 10:59:46

标签: javascript postgresql

我有一个PostgreSQL数据库,我使用node.js模块使用pg查询数据。我的Javascript代码(在服务器端)生成的数组包含许多重复值,因为这是返回数据的方式。我相信查询是可以的,因此值是重复的,因为多个INNER JOINS的表彼此独立,因此来自一个表的AB的结果({在这种情况下{1}},其他表格中qa_layersC的结果(本例中为D),以及来自第三个的公共值qa_cases table(在这种情况下为E)将表示为

qa_settings

据我所知,这应该是预期的行为。我需要做的是将每列的唯一数据过滤为具有唯一值的数组,例如| settings_name | layer_name | case_name | | E | A | C | | E | A | D | | E | B | C | | E | B | D | [A, B]的{​​{1}}和[C, D]。在我看来,有几种方法可以达到这个目的,但除非有一些我不知道的辅助库或功能,否则每一种方法看起来都有点痛苦。

  1. 在Javascript中从数据库中解析生成的数组。由于有多个for循环,这看起来很痛苦,但如果有一些库可以做我需要的东西,那可能很容易。
  2. 增强layer_name查询,以便不需要或不需要解析。我不知道这是否可行,但如果生成的数组中有更容易解析的对象,则解析可能不那么痛苦。我的查询最后粘贴了。
  3. 对数据库执行多次查询以获取正确的数据。对我来说,这似乎是最不可扩展的解决方案,在解析数组而不是运行多个连续查询时,开销会大大减少。
  4. 我的PostgreSQL查询:

    case_name

    我实际生成的Javascript数组:

    PostgreSQL

    我希望数组/ JSON最终如何:

    SELECT run.id, settings.name AS settings_name, layer.name AS layer_name, qa_case.name AS case_name FROM qa_runs AS run
        INNER JOIN qa_composites_in_run AS cr
            ON cr.run_id = run.id
        INNER JOIN qa_layers_in_composite AS lc
            ON lc.composite_name = cr.composite_name
        INNER JOIN qa_layers AS layer
            ON layer.name = lc.layer_name
        INNER JOIN qa_cases_in_run AS case_run
            ON case_run.run_id = run.id
        INNER JOIN qa_cases AS qa_case
            ON qa_case.name = case_run.case_name
        INNER JOIN qa_settings AS settings
            ON settings.name = run.settings_name
    WHERE run.id IN (27,28,29);
    

1 个答案:

答案 0 :(得分:1)

我建议在PostgreSQL端执行此操作,方法是使用嵌套数据构造并返回json对象,而不是返回连接关系。

使用9.3及以上版本的json支持,您可以相当轻松地完成此操作。如果没有示例数据和架构,我无法真正为您转换查询,但您需要从json_aggrow_to_json开始。查看其他相关问题以及引用这些功能的答案。

这是一个简单的例子:

CREATE TABLE parent(
    id integer primary key,
    parentdata text
);

CREATE TABLE child(
    id integer primary key,
    parent_id integer not null references parent(id),
    childdata text
);

INSERT INTO parent(id, parentdata) VALUES 
(1, 'p1'), (2, 'p2'), (3, 'p3');

INSERT INTO child(id, parent_id, childdata)
VALUES
(10, 1, 'c1_10'),
(20, 2, 'c2_20'),
(21, 2, 'c2_21');

SELECT row_to_json(toplevel, true)
FROM (
  SELECT p.id, p.parentdata, json_agg(c) AS children 
  FROM parent p 
  LEFT OUTER JOIN child c ON (p.id = c.parent_id) GROUP BY p.id
) toplevel;

发出:

{"id":1,
 "parentdata":"p1",
 "child":[{"id":10,"parent_id":1,"childdata":"c1_10"}]}
{"id":2,
 "parentdata":"p2",
 "child":[{"id":20,"parent_id":2,"childdata":"c2_20"}, 
 {"id":21,"parent_id":2,"childdata":"c2_21"}]}
{"id":3,
 "parentdata":"p3",
 "children":[null]}

如果必须重复删除,您可能希望通过确保完全指定SQL中的ORDER BY子句来执行此操作,以便从外部对象到内部对象排序。然后,您可以在js中线性扫描表,并忽略对象的id与上一行中同一实体的id相同的行。这是一个非常简单的单循环,带有一些状态跟踪变量。缺点是PostgreSQL必须对结果集进行排序。