【发布时间】:2014-11-24 10:05:37
【问题描述】:
我正在重构非常旧的代码。目前,PHP 为每个值生成一个单独的选择。假设loc 包含1,2 和data 包含a,b,它会生成
select val from tablename where loc_id=1 and data_id=a;
select val from tablename where loc_id=1 and data_id=b;
select val from tablename where loc_id=2 and data_id=a;
select val from tablename where loc_id=2 and data_id=b;
...等等,它们要么返回一个值,要么什么都不返回。这意味着我总是有 n(loc_id)*n(data_id) 结果,包括空值,这是后续处理所必需的。知道顺序后,这用于生成 HTML 表。 data_id 和 loc_id 理论上都可以扩展到数千个(这在表中显然不是很好,但这是另一个问题)。
+-----------+-----------+
| data_id 1 | data_id 2 |
+----------+-----------+-----------+
| loc_id 1 | - | 999.99 |
+----------+-----------+-----------+
+ loc_id 2 | 888.88 | - |
+----------+-----------+-----------+
为了加快速度,我正在考虑用单个查询替换它:
select val from tablename where loc_id in (1,2) and data_id in (a,b) order by loc_id asc, data_id asc;
得到类似(如下)的结果并迭代构建我的表。
Rownum VAL
------- --------
1 null
2 999.99
3 777.77
4 null
不幸的是,这种方法会从结果集中删除空值,所以我最终得到了
Rownum VAL
------- --------
1 999.99
2 777.77
请注意,data_id 或 loc_id 可能都没有任何匹配项,在这种情况下,我仍然需要 null, null。
所以我不知道哪个值匹配哪个。如果我添加 loc_id 和 data_id,我可以在 php 中匹配预期的 loc_id/data_id 组合......但这会变得混乱。
总的来说还是个 SQL 新手,这绝对是我第一次在 PostgreSQL 上工作,所以希望这不是太明显......当我发布这篇文章时,我正在寻找两种方法来解决这个问题:any in array[] 和 @987654334 @s。如果发现任何新内容会更新。
tl;博士问题
如何执行where loc_id in (1,2) and data_id in (a,b) 并保留空值,以便始终获得 n(loc)*n(data) 结果?
【问题讨论】:
-
“我不知道哪个值匹配哪个”——即使有 NULL,你也不知道。你还没有指定
order。 -
正确,我没有在上面指定。我会有一个 loc_id asc, data_id asc 的订单。
-
(loc_id, data_id)在您的表中定义是唯一的吗? (意味着您最多有 4 个没有 NULL 值的条目。)
标签: arrays postgresql join