我有一个PostgreSQL模型(在Django的上下文中生成),看起来像这样:
CREATE TABLE org (
id INTEGER NOT NULL,
parent_id INTEGER,
name CHARACTER VARYING(24),
org_type CHARACTER VARYING(8),
country CHARACTER VARYING(2)
)
CREATE TABLE rate (
id INTEGER NOT NULL,
org_id INTEGER NOT NULL,
rate DOUBLE PRECISION NOT NULL,
currency CHARACTER VARYING(3)
)
其中org_type是“组”,“公司”和“分支”之一。每个分支都有一个公司,只有公司属于一个组。给定一个任意的公司或分支机构以及一个国家/地区,我需要找到所有org_id是属于同一组并且在指定国家/地区的公司和分支机构的org_id的费率。因此,在下图中,对于公司123(在加拿大)或分支机构124(在多伦多),搜索“国家/地区”为“美国”的费率将在标记为“选定”的框中找到属于公司或分支机构的费率:
我正在为公司尝试以下操作,其中$1
是国家/地区代码,而$2
是组织ID:
SELECT rate.org_id, rate.rate, rate.currency
FROM rate, org
WHERE (
org.country = $1 AND
rate.org_id=org.id AND
org.parent_id = $2
) OR (
...
然后我陷入困境,试图弄清楚如何寻求属于我刚找到的公司之一的分支机构。我真的更喜欢一个大的WHERE子句,该子句可以带入任何相关组织的所有费率,这样我就不必对数据库进行一堆查询。
编辑
基于lau's answer,我尝试了一个示例(SQL fiddle),但这只是我刚开始的组织的回报率。
答案 0 :(得分:1)
您可以:
org
上应用条件org
作为起点,向上/向下浏览
UNION
组合2套JOIN
和费率(下面我做了LEFT OUTER JOIN
以便明确说明递归中确切包含的内容)。示例:
WITH RECURSIVE SelectedOrg AS (
SELECT * FROM org WHERE id = 4
),
BrowseOrg AS (
SELECT 1 AS Direction, * FROM SelectedOrg
UNION ALL
SELECT -1, * FROM SelectedOrg
UNION ALL
SELECT Direction, org.* FROM org JOIN BrowseOrg ON (direction = 1 and org.parent_id = BrowseOrg.id) OR (direction = -1 and org.id = BrowseOrg.parent_id)
)
SELECT DISTINCT rates.id, BrowseOrg.id, rates.rate FROM BrowseOrg LEFT OUTER JOIN rates ON org_id = BrowseOrg.id
这将足够灵活以处理您不知道所选org
级别(组,公司或分支机构)的情况。
将来,这也应该能够应付更深层次的层次结构(如果您向层次结构添加了层次)。
答案 1 :(得分:0)
您可以在2个查询中使用一些子查询来实现。
让company_org_ids = select id from org where country code = $1 and parent_id = $2
Select distinct rate.* from rate where orgid in ($3) or where orgid in (select id from org where parent_id in $3 and country_code =$1)
这里$ 3是第一个查询的company_org_ids
结果。
此外,也可以通过将$3
变量替换为第一个查询来完成单个查询。