【问题标题】:sql filter rows based on condition parent to child hierarchysql根据条件父子层次结构过滤行
【发布时间】:2013-12-27 08:26:30
【问题描述】:

Erwin,我对正确的示例和数据不好。请根据需要在下面找到包含所有数据的更新查询。 我们有一个主表,其中包含资产 ID 之间的所有关系,如下所示。资产层次结构是 S1,它有 F11、F12、F13,而 F11 有 D111、D112、D113,同样 F12 有 D121、D122、D123 等等。

主表和插入脚本

请参考链接sqlfiddle

CREATE TABLE tbl2 (c_id text ,d_id text, f_id text, s_id text);
INSERT INTO tbl2 values('100000019403','D111','F11','S1');
INSERT INTO tbl2 values('100000019404','D112','F11','S1');
INSERT INTO tbl2 values('100000019405','D113','F11','S1');
INSERT INTO tbl2 values('100000019406','D111','F11','S1');
INSERT INTO tbl2 values('100000019407','D112','F11','S1');
INSERT INTO tbl2 values('100000019408','D121','F12','S1');
INSERT INTO tbl2 values('100000019409','D122','F12','S1');
INSERT INTO tbl2 values('100000019410','D123','F12','S1');
INSERT INTO tbl2 values('100000019411','D123','F12','S1');
INSERT INTO tbl2 values('100000019412','D141','F14','S1');
INSERT INTO tbl2 values('100000019413','D131','F13','S1');
INSERT INTO tbl2 values('100000019414','D142','F14','S1');
INSERT INTO tbl2 values('100000019415','D132','F13','S1');
INSERT INTO tbl2 values('100000019416','D143','F14','S1');
INSERT INTO tbl2 values('100000019417','D133','F13','S1');
INSERT INTO tbl2 values('100000019418','D144','F14','S1');
INSERT INTO tbl2 values('100000019419','D211','F21','S2');
INSERT INTO tbl2 values('100000019420','D212','F21','S2');
INSERT INTO tbl2 values('100000019421','D213','F21','S2');
INSERT INTO tbl2 values('100000019422','D211','F21','S2');
INSERT INTO tbl2 values('100000019423','D212','F21','S2');
INSERT INTO tbl2 values('100000019424','D221','F22','S2');
INSERT INTO tbl2 values('100000019425','D222','F22','S2');
INSERT INTO tbl2 values('100000019426','D223','F22','S2');
INSERT INTO tbl2 values('100000019427','D223','F22','S2');
INSERT INTO tbl2 values('100000019428','D241','F24','S2');
INSERT INTO tbl2 values('100000019429','D231','F23','S2');
INSERT INTO tbl2 values('100000019430','D242','F24','S2');
INSERT INTO tbl2 values('100000019431','D232','F23','S2');
INSERT INTO tbl2 values('100000019432','D243','F24','S2');
INSERT INTO tbl2 values('100000019433','D233','F23','S2');
INSERT INTO tbl2 values('100000019434','D244','F24','S2');
INSERT INTO tbl2 values('100000019435','D311','F31','S3');
INSERT INTO tbl2 values('100000019436','D312','F31','S3');
INSERT INTO tbl2 values('100000019437','D313','F31','S3');
INSERT INTO tbl2 values('100000019438','D311','F31','S3');
INSERT INTO tbl2 values('100000019439','D312','F31','S3');
INSERT INTO tbl2 values('100000019440','D321','F32','S3');
INSERT INTO tbl2 values('100000019441','D322','F32','S3');
INSERT INTO tbl2 values('100000019442','D323','F32','S3');
INSERT INTO tbl2 values('100000019443','D323','F32','S3');
INSERT INTO tbl2 values('100000019444','D341','F34','S3');
INSERT INTO tbl2 values('100000019445','D331','F33','S3');
INSERT INTO tbl2 values('100000019446','D342','F34','S3');
INSERT INTO tbl2 values('100000019447','D332','F33','S3');
INSERT INTO tbl2 values('100000019448','D343','F34','S3');
INSERT INTO tbl2 values('100000019449','D333','F33','S3');
INSERT INTO tbl2 values('100000019450','D344','F34','S3');
INSERT INTO tbl2 values('100000019451','D111','F11','S1');
INSERT INTO tbl2 values('100000019452','D112','F11','S1');
INSERT INTO tbl2 values('100000019453','D113','F11','S1');
INSERT INTO tbl2 values('100000019454','D111','F11','S1');
INSERT INTO tbl2 values('100000019455','D112','F11','S1');
INSERT INTO tbl2 values('100000019456','D121','F12','S1');
INSERT INTO tbl2 values('100000019457','D122','F12','S1');
INSERT INTO tbl2 values('100000019458','D123','F12','S1');
INSERT INTO tbl2 values('100000019459','D123','F12','S1');
INSERT INTO tbl2 values('100000019460','D141','F14','S1');
INSERT INTO tbl2 values('100000019461','D131','F13','S1');
INSERT INTO tbl2 values('100000019462','D142','F14','S1');
INSERT INTO tbl2 values('100000019463','D132','F13','S1');
INSERT INTO tbl2 values('100000019464','D143','F14','S1');
INSERT INTO tbl2 values('100000019465','D133','F13','S1');
INSERT INTO tbl2 values('100000019466','D144','F14','S1');

我们有带有资产 ID 的事务表,它仅提供有关失败资产的信息。假设如果更高级别的资产 ID 失败,则子项的数据也会被填充,但在获取记录时,我们需要忽略子项并仅获取最高级别​​。

交易数据可提供 3 天,其中讨论了三种不同的场景。 2013 年 10 月 10 日的场景 1 讨论了 S1 资产失败,这也给出了需要忽略的子记录。

2013 年 10 月 11 日的场景 2,其中涉及 F21、F22、F23 故障及其子记录。我们需要忽略孩子。观察资产 ID S1 没有失败,因此不会出现在场景 2 的事务表中

2013 年 10 月 12 日的场景 3,其中谈到 F33 故障及其子项 D331、D332、D333。我们只需要考虑 F33 而忽略孩子。考虑 D311、D312、D313、D321、D322 和 D323。

我们总是需要按 startdatetime 字段分组,因为父记录和子记录对于给定条目将始终具有相同的列值。

参考上面的链接,里面也有事务表和数据

CREATE TABLE tbl1 (startdatetime text, enddatetime text, assetid text);

INSERT INTO tbl1  values('2013-10-10 22:10:11', '2013-10-10 22:10:11', 'S1');
 INSERT INTO tbl1  values('2013-10-10 22:10:11', '2013-10-10 22:10:11', 'F11');
 INSERT INTO tbl1  values('2013-10-10 22:10:11', '2013-10-10 22:10:11', 'F12');
 INSERT INTO tbl1  values('2013-10-10 22:10:11', '2013-10-10 22:10:11', 'F13');
 INSERT INTO tbl1  values('2013-10-10 22:10:11', '2013-10-10 22:10:11', 'D111');
 INSERT INTO tbl1  values('2013-10-10 22:10:11', '2013-10-10 22:10:11', 'D112');
 INSERT INTO tbl1  values('2013-10-10 22:10:11', '2013-10-10 22:10:11', 'D113');
 INSERT INTO tbl1  values('2013-10-10 22:10:11', '2013-10-10 22:10:11', 'D121');
 INSERT INTO tbl1  values('2013-10-10 22:10:11', '2013-10-10 22:10:11', 'D122');
 INSERT INTO tbl1  values('2013-10-10 22:10:11', '2013-10-10 22:10:11', 'D123');
 INSERT INTO tbl1  values('2013-10-10 22:10:11', '2013-10-10 22:10:11', 'D131');
 INSERT INTO tbl1  values('2013-10-10 22:10:11', '2013-10-10 22:10:11', 'D132');
 INSERT INTO tbl1  values('2013-10-10 22:10:11', '2013-10-10 22:10:11', 'D133');

 INSERT INTO tbl1  values('2013-10-11 22:10:11', '2013-10-11 22:12:11', 'F21');
 INSERT INTO tbl1  values('2013-10-11 22:10:11', '2013-10-11 22:12:11', 'F22');
 INSERT INTO tbl1  values('2013-10-11 22:10:11', '2013-10-11 22:12:11', 'F23');
 INSERT INTO tbl1  values('2013-10-11 22:10:11', '2013-10-11 22:12:11', 'D211');
 INSERT INTO tbl1  values('2013-10-11 22:10:11', '2013-10-11 22:12:11', 'D212');
 INSERT INTO tbl1  values('2013-10-11 22:10:11', '2013-10-11 22:12:11', 'D213');
 INSERT INTO tbl1  values('2013-10-11 22:10:11', '2013-10-11 22:12:11', 'D221');
 INSERT INTO tbl1  values('2013-10-11 22:10:11', '2013-10-11 22:12:11', 'D222');
 INSERT INTO tbl1  values('2013-10-11 22:10:11', '2013-10-11 22:12:11', 'D223');
 INSERT INTO tbl1  values('2013-10-11 22:10:11', '2013-10-11 22:12:11', 'D231');
 INSERT INTO tbl1  values('2013-10-11 22:10:11', '2013-10-11 22:12:11', 'D232');
 INSERT INTO tbl1  values('2013-10-11 22:10:11', '2013-10-11 22:12:11', 'D233');

 INSERT INTO tbl1  values('2013-10-12 22:10:11', '2013-10-12 22:16:11', 'F33');
 INSERT INTO tbl1  values('2013-10-12 22:10:11', '2013-10-12 22:16:11', 'D311');
 INSERT INTO tbl1  values('2013-10-12 22:10:11', '2013-10-12 22:16:11', 'D312');
 INSERT INTO tbl1  values('2013-10-12 22:10:11', '2013-10-12 22:16:11', 'D313');
 INSERT INTO tbl1  values('2013-10-12 22:10:11', '2013-10-12 22:16:11', 'D321');
 INSERT INTO tbl1  values('2013-10-12 22:10:11', '2013-10-12 22:16:11', 'D322');
 INSERT INTO tbl1  values('2013-10-12 22:10:11', '2013-10-12 22:16:11', 'D323');
 INSERT INTO tbl1  values('2013-10-12 22:10:11', '2013-10-12 22:16:11', 'D331');
 INSERT INTO tbl1  values('2013-10-12 22:10:11', '2013-10-12 22:16:11', 'D332');
 INSERT INTO tbl1  values('2013-10-12 22:10:11', '2013-10-12 22:16:11', 'D333');

预期输出:

根据交易数据表,受影响的消费者数量。

请帮我提供上述场景的 c_id 记录详细信息,我会得到计数。

【问题讨论】:

  • 请仍然显示您的查询,即使它根本不起作用。它通常会澄清你所追求的。到目前为止,还不清楚结果中应包含哪些列或应如何对行进行排序。
  • 此外,层次结构似乎完全不相关。无论层次结构如何,在您的示例中始终会忽略关联的 ID。

标签: sql postgresql postgresql-9.1


【解决方案1】:

case1 : s_id 存在然后忽略 child(f_id) 和 subchild(d_id) 行

使用CTEs,解决方案可能如下所示:

WITH x AS (
   SELECT d_id, f_id
   FROM   tbl2 t2
   JOIN   tbl1 t1 ON t1.assetid = t2.s_id
   )
SELECT t.*
FROM   tbl1 t
LEFT   JOIN d ON d.d_id = t.assetid
LEFT   JOIN f ON f.f_id = t.assetid
WHERE  d.d_id IS NULL
AND    f.f_id IS NULL

解释

  • CTE x 标识应被忽略的 d_idf_id
  • 主 SELECT 左连接到此排除表 x 两次,以消除在 d_idf_id 上匹配的行。

case2 : f_id 存在然后忽略 parent(s_id) 和 lower(d_id)

WITH x AS (
   SELECT d_id, s_id
   FROM   tbl2 f
   JOIN   tbl1 t ON t.assetid = f.f_id
   )
SELECT t.*
FROM   tbl1 t
LEFT   JOIN x d ON d.d_id = t.assetid
LEFT   JOIN x s ON s.s_id = t.assetid
WHERE  d.d_id IS NULL
AND    s.s_id IS NULL;

-> SQLfiddle demo

case3 : d_id 存在然后忽略父 s_id,f_id

你明白了,不是吗?

【讨论】:

  • @sandy067:我认为你错了。查询应该按原样工作。 d_idf_id 在你的小提琴中切换。考虑/比较this fixed fiddle
  • 感谢 Erwin 这正是我想要的,尽管这里是预期输出 sqlFiddle 的链接。一个查询会返回我所期望的所有结果。抱歉,对于给定的资产 ID,我可能有不同的时间记录,我需要捕获这些时间记录,并且存在于上面提供的最新小提琴中。非常感谢您的帮助!!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-23
相关资源
最近更新 更多