【问题标题】:Displaying rows in which the column value does not appear in the same group of another column显示列值未出现在另一列的同一组中的行
【发布时间】:2023-03-20 05:02:01
【问题描述】:

我正在尝试编写正确的查询,但它们显示的结果不正确。 例如,我有表 ABC:

id a_id b_id c 1 10 100 2 10 111 3 11 111 4 11 222 5 11 333 111&&222&&333 6 12 444 7 12 555 444&&111

在 c 列中只能有 b_id 和 && 属于同一个 a_id。 比如这条记录不正确:

7 12 555 444&111

因为 111 在 a_id 10 或 11 而不是 12 中。我怎样才能找到它? 我需要找到 C 列中出现(无效)值 b_id 且不在同一个 a_id 中的所有行。 Sql(postgresql) 不能正常工作,为什么?感谢您的帮助。

我的 sql:

选择 * 从 ABC x 在哪里 x.id (选择 y.id 从 ABC y 其中 x.a_id = y.a_ai AND y.c NOT LIKE '%'||x.b_id||'%'

【问题讨论】:

  • 您已标记三个 DBMS 产品。这是否意味着,查询应该在所有这些或任何一个中工作?
  • 既然你提到了“postgresql”——我已经删除了mysqlsql-server标签。
  • Paul 查询应该找到所有不正确的记录,其中列 C 具有错误的值 b_id。将 a_id 视为一个组,将 b_id 视为该组中的用户,而 C 只能包含来自其组的任意数量的用户,它不能来自另一个用户,如最后一行 id 为 7 的用户。可能有 444 和/或 555 。好的,感谢您删除标签

标签: sql postgresql


【解决方案1】:

假设b_id在表中是唯一的,你可以使用:

select abc.*
from abc
where exists (select 1
              from abc abc2
              where abc2.a_id = abc.a_id and
                    concat('&&', abc2.c, '&&') not like concat('%&&', abc.b_id, '&&%')
             );

【讨论】:

  • @嗨,戈登。对不起,我没有给它,但 b_id 不是唯一的
【解决方案2】:

使用regexp_split_to_table() 将分隔字符串拆分为行。然后使用 anti-join 方法,找到不匹配的条目:

with t1 as (
  select *, regexp_split_to_table(c, '&&')::int AS split_c
  from abc
  where c <> ''
)
select distinct t1.id, t1.a_id, t1.b_id, t1.c
from t1
left join abc t2
  on  t2.a_id = t1.a_id
  and t2.b_id = t1.split_c
where t2.a_id is null

demo on db-fiddle.com

您也可以使用NOT EXISTS 子查询来代替反连接

with t1 as (
  select *, regexp_split_to_table(c, '&&')::int AS split_c
  from abc
  where c <> ''
)
select distinct t1.id, t1.a_id, t1.b_id, t1.c
from t1
where not exists (
  select *
  from abc t2
  where t2.a_id = t1.a_id
    and t2.b_id = t1.split_c
)

如果您还想知道c 中的哪个值是错误的,请将select distinct ... 替换为select t1.*。您将在split_c 列中找到“错误”值。或者使用GROUP BYarray_agg() 在一行中列出所有错误值:

with t1 as (
  select *, regexp_split_to_table(c, '&&')::int AS split_c
  from abc
  where c <> ''
)
select t1.id, t1.a_id, t1.b_id, t1.c, array_agg(t1.split_c) as wrong_c
from t1
left join abc t2
  on  t2.a_id = t1.a_id
  and t2.b_id = t1.split_c
where t2.a_id is null
group by t1.id, t1.a_id, t1.b_id, t1.c

【讨论】:

  • 再次感谢 Paul 的宝贵建议!
猜你喜欢
  • 1970-01-01
  • 2022-01-12
  • 1970-01-01
  • 2019-12-01
  • 2022-08-17
  • 1970-01-01
  • 2019-09-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多