查询五张表,包括两张相互关联的联结表,形成View
Query five tables including two inter-related junction tables to form View
我有三个tables (surveypoint, sample, fldwrk_images):一个surveypoint可以有很多或没有样本,surveypoint和sample都可以有很多或没有图像,surveypoint都可以和样本链接到两个单独的结点 table,因为图像可以是一个或多个 samples/surveypoints。这两个多对多关系由连接 table fldwrk_images.
的两个连接点 table(svypnt_fldwrk_image_junc 和 sample_fldwrk_image_junc)形成
我正在尝试创建一个视图,使每一行都包含测量点信息、与测量点相关的示例信息(如果有)和图像信息(如果有)。由于图像来自交界处 tables,我希望在测量点和样本上有重复的信息,这很好,但我希望视图在 image_id.
上是不同的
下面是我尝试的查询,当 运行 永远持续下去时,很明显它是有缺陷的,我不知道该怎么做。
CREATE OR REPLACE VIEW query_fldwrk_images_by_surveypoint_and_sample AS
SELECT DISTINCT ON (fi1.fldwrk_image_id) svypnt_fldwrk_image_junc.svypnt_fldwrk_image_junc_id,
fi1.image_path,
fi1.image_name,
fi1.iptc_caption,
fi1.iptc_keywords,
srpnt1.surveypoint_name,
fi1.fldwrk_image_id,
sam1.sample_name
FROM surveypoint as srpnt1
LEFT JOIN sample sam2 ON srpnt1.surveypoint_id = sam2.surveypoint_id,
svypnt_fldwrk_image_junc
LEFT JOIN fldwrk_image fi1 ON svypnt_fldwrk_image_junc.fldwrk_image_id = fi1.fldwrk_image_id
LEFT JOIN surveypoint srpnt2 ON svypnt_fldwrk_image_junc.surveypoint_id = srpnt2.surveypoint_id,
sample_fldwrk_image_junc
LEFT JOIN fldwrk_image fi2 ON sample_fldwrk_image_junc.fldwrk_image_id = fi2.fldwrk_image_id
LEFT JOIN sample sam1 ON sample_fldwrk_image_junc.sample_id = sam1.sample_id;
交叉连接
问题是这个
FROM surveypoint as srpnt1
LEFT JOIN sample sam2 ON srpnt1.surveypoint_id = sam2.surveypoint_id
不以任何方式加入此
svypnt_fldwrk_image_junc
LEFT JOIN fldwrk_image fi1 ON svypnt_fldwrk_image_junc.fldwrk_image_id = fi1.fldwrk_image_id
LEFT JOIN surveypoint srpnt2 ON svypnt_fldwrk_image_junc.surveypoint_id = srpnt2.surveypoint_id
并且都没有加入这个
sample_fldwrk_image_junc
LEFT JOIN fldwrk_image fi2 ON sample_fldwrk_image_junc.fldwrk_image_id = fi2.fldwrk_image_id
LEFT JOIN sample sam1 ON sample_fldwrk_image_junc.sample_id = sam1.sample_id
(请注意,table 别名在 surveypoint
和 sample
上是不同的。)这将创建一个 CROSS JOIN
,从而产生三组 tables。如果每个组有 1,000 条记录,则视图将有 1,000,000,000 条记录,这需要 一些 时间来准备。
更改 sample
和 surveypoint
的别名并重新安排连接顺序将使您的视图快速准备就绪。
区分开
您注意到您希望视图是 DISTINCT ON
与 surveypoint
关联的 image_id
。这里有几点需要考虑:
- 除非您包含
ORDER BY
子句,否则保留在视图中的记录是不确定的,甚至达到针对视图的单独查询可以显示不同结果的程度。
- 显然,一个
surveypoint
可以有很多图像,一个图像可以与一个 surveypoint
及其任何一个 sample
相关联。美好的。但是一张图片可以关联多个 surveypoint
吗?这听起来不太合逻辑。
改写你的叙述(并添加一些根据你在问题中的查询似乎有意义的猜测),你似乎想要这个(伪SQL):
CREATE VIEW query_fldwrk_images_by_surveypoint_and_sample AS
SELECT surveypoint_info, sample_info, image_info
WHERE image_info IS ANY image_info LINKED TO svy_pnt
OR ELSE ANY image_info LINKED TO ANY smpl LINKED TO svy_pnt NOT USED IN OTHER RECORDS
由于两条路径上的多对多关系以及 DISTINCT ON
和 image_id 的要求,这不能以确定性的方式在简单查询中完成。简而言之,问题是您必须创建 surveypoint-sample-image
的组合并跟踪您分配的图像位置,如果您在某处遇到 NULL
可能会回溯(例如,您可以有一个 surveypoint
没有图像 linked,所以你使用第一个可用的图像 sample
。如果任何其他样本只有该图像 linked,它'将在没有有效图像的情况下出现(因为 DISTINCT ON
子句),而其他示例中可能有 "extra" 个图像。
您应该放宽 DISTINCT ON
要求,使此视图相对简单。这种放松可以是以下形式: 给所有测量点及其样本和测量点的图像;如果图像是NULL
,则使用样本点的任何图像。您最终可能会得到来自不同样本的相同图像,但至少您会有自己的观点。
我认为这可能有效的唯一方法是颠倒逻辑:不是 link 将图像用于测量点和样本,link 后者用于图像,但是你'将遇到与多对多冲突相同的问题(即哪个测量点或样本分配给哪个图像)。递归 CTE 会完成艰苦的工作,但解决冲突仍然非常困难。
(我正在回答我自己的问题以引出 replies/comments 我的新数据库结构:我不确定这是否符合礼节...)
根据 Patrick 提供的第一个答案,由于我的数据库是结构化的,所以我无法查询它来提取我需要的信息。为了解决这个问题,我重组了数据库,从两个连接三个 table 的连接 table 到一个连接三个 table 的连接 table,新的连接 table 有一个 junction_pk、一个 image_id、一个 surveypoint_id 和一个 sample_id。由于一些测量点没有相关样本,在新交汇点 table 中有一些行没有 sample_id 数据。
为了提取我需要的所有信息,我在调查点上使用 select distinct on junction_id 创建了一个视图,首先使用 sample_id is null 然后在 [=28 上使用 union =] 不为空(这似乎是必需的,否则没有关联样本的调查点上的数据显示为空,因为无法说 sample_id 彼此相关)。
新结构似乎可以工作并且不会在我需要的视图中产生错误的连接(该视图基于另一个查询 - query.1 - 它首先查询六个 tables 以汇集所需的信息与图像相关联)。
我的问题是:这种联结 table 是否链接了数据库中的三个 table 良好实践:这会导致我不知道的问题吗?我创建视图的方式是使用 union 方法 appropriate/efficient?
查询是:
CREATE OR REPLACE VIEW query_surv_sam_images_irll14 AS
SELECT DISTINCT ON (junc1.svy_sam_image_junc_id) fi1.iptc_caption,
query1.surveypoint_name,
query1.sample_name,
query1.material_name,
query1.surv_formation_name,
query1.surv_newcode,
query1.samp_formation_name,
query1.samp_newcode,
query1.surveypoint_type_name,
query1.surveypoint_descrp_brief,
query1.surveypoint_description,
query1.survey_date,
query1.sample_type_name,
query1.geochemical,
query1.outcrop_grp_name,
query1.outcrop_grp_descrp,
query1.locality_name,
query1.area_name,
query1.waterbasin_name,
query1.townland_name,
query1.county,
query1.country_name,
junc1.svy_sam_image_junc_id,
junc1.surveypoint_id,
query1.surv_id,
junc1.sample_id,
query1.samp_id,
fi1.image_name,
fi1.image_path,
fi1.geom
FROM svy_sam_image_junc junc1
JOIN fldwrk_image fi1 ON fi1.fldwrk_image_id = junc1.fldwrk_image_id
LEFT JOIN query_srpnts_samples_irll14 query1 ON query1.surv_id = junc1.surveypoint_id
WHERE junc1.sample_id IS NULL
UNION
SELECT DISTINCT ON (junc1.svy_sam_image_junc_id) fi1.iptc_caption,
query1.surveypoint_name,
query1.sample_name,
query1.material_name,
query1.surv_formation_name,
query1.surv_newcode,
query1.samp_formation_name,
query1.samp_newcode,
query1.surveypoint_type_name,
query1.surveypoint_descrp_brief,
query1.surveypoint_description,
query1.survey_date,
query1.sample_type_name,
query1.geochemical,
query1.outcrop_grp_name,
query1.outcrop_grp_descrp,
query1.locality_name,
query1.area_name,
query1.waterbasin_name,
query1.townland_name,
query1.county,
query1.country_name,
junc1.svy_sam_image_junc_id,
junc1.surveypoint_id,
query1.surv_id,
junc1.sample_id,
query1.samp_id,
fi1.image_name,
fi1.image_path,
fi1.geom
FROM svy_sam_image_junc junc1
JOIN fldwrk_image fi1 ON fi1.fldwrk_image_id = junc1.fldwrk_image_id
LEFT JOIN query_srpnts_samples_irll14 query1 ON query1.samp_id = junc1.sample_id
WHERE junc1.sample_id IS NOT NULL
ORDER BY 2, 3, 1, 28;
我有三个tables (surveypoint, sample, fldwrk_images):一个surveypoint可以有很多或没有样本,surveypoint和sample都可以有很多或没有图像,surveypoint都可以和样本链接到两个单独的结点 table,因为图像可以是一个或多个 samples/surveypoints。这两个多对多关系由连接 table fldwrk_images.
的两个连接点 table(svypnt_fldwrk_image_junc 和 sample_fldwrk_image_junc)形成我正在尝试创建一个视图,使每一行都包含测量点信息、与测量点相关的示例信息(如果有)和图像信息(如果有)。由于图像来自交界处 tables,我希望在测量点和样本上有重复的信息,这很好,但我希望视图在 image_id.
上是不同的下面是我尝试的查询,当 运行 永远持续下去时,很明显它是有缺陷的,我不知道该怎么做。
CREATE OR REPLACE VIEW query_fldwrk_images_by_surveypoint_and_sample AS
SELECT DISTINCT ON (fi1.fldwrk_image_id) svypnt_fldwrk_image_junc.svypnt_fldwrk_image_junc_id,
fi1.image_path,
fi1.image_name,
fi1.iptc_caption,
fi1.iptc_keywords,
srpnt1.surveypoint_name,
fi1.fldwrk_image_id,
sam1.sample_name
FROM surveypoint as srpnt1
LEFT JOIN sample sam2 ON srpnt1.surveypoint_id = sam2.surveypoint_id,
svypnt_fldwrk_image_junc
LEFT JOIN fldwrk_image fi1 ON svypnt_fldwrk_image_junc.fldwrk_image_id = fi1.fldwrk_image_id
LEFT JOIN surveypoint srpnt2 ON svypnt_fldwrk_image_junc.surveypoint_id = srpnt2.surveypoint_id,
sample_fldwrk_image_junc
LEFT JOIN fldwrk_image fi2 ON sample_fldwrk_image_junc.fldwrk_image_id = fi2.fldwrk_image_id
LEFT JOIN sample sam1 ON sample_fldwrk_image_junc.sample_id = sam1.sample_id;
交叉连接
问题是这个
FROM surveypoint as srpnt1
LEFT JOIN sample sam2 ON srpnt1.surveypoint_id = sam2.surveypoint_id
不以任何方式加入此
svypnt_fldwrk_image_junc
LEFT JOIN fldwrk_image fi1 ON svypnt_fldwrk_image_junc.fldwrk_image_id = fi1.fldwrk_image_id
LEFT JOIN surveypoint srpnt2 ON svypnt_fldwrk_image_junc.surveypoint_id = srpnt2.surveypoint_id
并且都没有加入这个
sample_fldwrk_image_junc
LEFT JOIN fldwrk_image fi2 ON sample_fldwrk_image_junc.fldwrk_image_id = fi2.fldwrk_image_id
LEFT JOIN sample sam1 ON sample_fldwrk_image_junc.sample_id = sam1.sample_id
(请注意,table 别名在 surveypoint
和 sample
上是不同的。)这将创建一个 CROSS JOIN
,从而产生三组 tables。如果每个组有 1,000 条记录,则视图将有 1,000,000,000 条记录,这需要 一些 时间来准备。
更改 sample
和 surveypoint
的别名并重新安排连接顺序将使您的视图快速准备就绪。
区分开
您注意到您希望视图是 DISTINCT ON
与 surveypoint
关联的 image_id
。这里有几点需要考虑:
- 除非您包含
ORDER BY
子句,否则保留在视图中的记录是不确定的,甚至达到针对视图的单独查询可以显示不同结果的程度。 - 显然,一个
surveypoint
可以有很多图像,一个图像可以与一个surveypoint
及其任何一个sample
相关联。美好的。但是一张图片可以关联多个surveypoint
吗?这听起来不太合逻辑。
改写你的叙述(并添加一些根据你在问题中的查询似乎有意义的猜测),你似乎想要这个(伪SQL):
CREATE VIEW query_fldwrk_images_by_surveypoint_and_sample AS
SELECT surveypoint_info, sample_info, image_info
WHERE image_info IS ANY image_info LINKED TO svy_pnt
OR ELSE ANY image_info LINKED TO ANY smpl LINKED TO svy_pnt NOT USED IN OTHER RECORDS
由于两条路径上的多对多关系以及 DISTINCT ON
和 image_id 的要求,这不能以确定性的方式在简单查询中完成。简而言之,问题是您必须创建 surveypoint-sample-image
的组合并跟踪您分配的图像位置,如果您在某处遇到 NULL
可能会回溯(例如,您可以有一个 surveypoint
没有图像 linked,所以你使用第一个可用的图像 sample
。如果任何其他样本只有该图像 linked,它'将在没有有效图像的情况下出现(因为 DISTINCT ON
子句),而其他示例中可能有 "extra" 个图像。
您应该放宽 DISTINCT ON
要求,使此视图相对简单。这种放松可以是以下形式: 给所有测量点及其样本和测量点的图像;如果图像是NULL
,则使用样本点的任何图像。您最终可能会得到来自不同样本的相同图像,但至少您会有自己的观点。
我认为这可能有效的唯一方法是颠倒逻辑:不是 link 将图像用于测量点和样本,link 后者用于图像,但是你'将遇到与多对多冲突相同的问题(即哪个测量点或样本分配给哪个图像)。递归 CTE 会完成艰苦的工作,但解决冲突仍然非常困难。
(我正在回答我自己的问题以引出 replies/comments 我的新数据库结构:我不确定这是否符合礼节...)
根据 Patrick 提供的第一个答案,由于我的数据库是结构化的,所以我无法查询它来提取我需要的信息。为了解决这个问题,我重组了数据库,从两个连接三个 table 的连接 table 到一个连接三个 table 的连接 table,新的连接 table 有一个 junction_pk、一个 image_id、一个 surveypoint_id 和一个 sample_id。由于一些测量点没有相关样本,在新交汇点 table 中有一些行没有 sample_id 数据。
为了提取我需要的所有信息,我在调查点上使用 select distinct on junction_id 创建了一个视图,首先使用 sample_id is null 然后在 [=28 上使用 union =] 不为空(这似乎是必需的,否则没有关联样本的调查点上的数据显示为空,因为无法说 sample_id 彼此相关)。
新结构似乎可以工作并且不会在我需要的视图中产生错误的连接(该视图基于另一个查询 - query.1 - 它首先查询六个 tables 以汇集所需的信息与图像相关联)。
我的问题是:这种联结 table 是否链接了数据库中的三个 table 良好实践:这会导致我不知道的问题吗?我创建视图的方式是使用 union 方法 appropriate/efficient?
查询是:
CREATE OR REPLACE VIEW query_surv_sam_images_irll14 AS
SELECT DISTINCT ON (junc1.svy_sam_image_junc_id) fi1.iptc_caption,
query1.surveypoint_name,
query1.sample_name,
query1.material_name,
query1.surv_formation_name,
query1.surv_newcode,
query1.samp_formation_name,
query1.samp_newcode,
query1.surveypoint_type_name,
query1.surveypoint_descrp_brief,
query1.surveypoint_description,
query1.survey_date,
query1.sample_type_name,
query1.geochemical,
query1.outcrop_grp_name,
query1.outcrop_grp_descrp,
query1.locality_name,
query1.area_name,
query1.waterbasin_name,
query1.townland_name,
query1.county,
query1.country_name,
junc1.svy_sam_image_junc_id,
junc1.surveypoint_id,
query1.surv_id,
junc1.sample_id,
query1.samp_id,
fi1.image_name,
fi1.image_path,
fi1.geom
FROM svy_sam_image_junc junc1
JOIN fldwrk_image fi1 ON fi1.fldwrk_image_id = junc1.fldwrk_image_id
LEFT JOIN query_srpnts_samples_irll14 query1 ON query1.surv_id = junc1.surveypoint_id
WHERE junc1.sample_id IS NULL
UNION
SELECT DISTINCT ON (junc1.svy_sam_image_junc_id) fi1.iptc_caption,
query1.surveypoint_name,
query1.sample_name,
query1.material_name,
query1.surv_formation_name,
query1.surv_newcode,
query1.samp_formation_name,
query1.samp_newcode,
query1.surveypoint_type_name,
query1.surveypoint_descrp_brief,
query1.surveypoint_description,
query1.survey_date,
query1.sample_type_name,
query1.geochemical,
query1.outcrop_grp_name,
query1.outcrop_grp_descrp,
query1.locality_name,
query1.area_name,
query1.waterbasin_name,
query1.townland_name,
query1.county,
query1.country_name,
junc1.svy_sam_image_junc_id,
junc1.surveypoint_id,
query1.surv_id,
junc1.sample_id,
query1.samp_id,
fi1.image_name,
fi1.image_path,
fi1.geom
FROM svy_sam_image_junc junc1
JOIN fldwrk_image fi1 ON fi1.fldwrk_image_id = junc1.fldwrk_image_id
LEFT JOIN query_srpnts_samples_irll14 query1 ON query1.samp_id = junc1.sample_id
WHERE junc1.sample_id IS NOT NULL
ORDER BY 2, 3, 1, 28;