SQL查询(Postgres)如何回答?

SQL查询(Postgres)如何回答?,sql,postgresql,Sql,Postgresql,我有一个带有公司id(非唯一)和一些属性(我们称之为状态id)的表,状态可以在1到18之间(多对多行id是唯一的) 现在我需要得到只有1和18行的公司的结果,如果他们也有任何数字(比如3),那么这个公司就不应该被返回。 数据存储为行id、一些元数据、公司id和一个状态id,下面的示例是在我运行GROUPBY查询之后 作为一个例子,如果我使用group by和string agg,我会得到以下值: Company ID Status 1 1,9,12,18 2

我有一个带有公司id(非唯一)和一些属性(我们称之为状态id)的表,状态可以在1到18之间(多对多行id是唯一的) 现在我需要得到只有1和18行的公司的结果,如果他们也有任何数字(比如3),那么这个公司就不应该被返回。 数据存储为行id、一些元数据、公司id和一个状态id,下面的示例是在我运行GROUPBY查询之后

作为一个例子,如果我使用group by和string agg,我会得到以下值:

Company ID Status
1           1,9,12,18
2           12,13,18
3           1
4           8
5           18

所以在这种情况下,我只需要返回3和5。

您应该修复数据模型。以下是一些原因:

  • 用字符串存储数字是不好的
  • 在字符串中存储多个值是错误的
  • SQL的字符串处理能力很差
  • Postgres提供了许多存储多个值的方法——一个连接表、数组和JSON
对于您的特定问题,进行显式比较如何

where status in ('1', '18', '1,18', '18,1')

您应该修复数据模型。以下是一些原因:

  • 用字符串存储数字是不好的
  • 在字符串中存储多个值是错误的
  • SQL的字符串处理能力很差
  • Postgres提供了许多存储多个值的方法——一个连接表、数组和JSON
对于您的特定问题,进行显式比较如何

where status in ('1', '18', '1,18', '18,1')

你可以利用小组和拥有。即:

select * 
from myTable 
where statusId in (1,18)
and companyId in (select companyId 
  from myTable 
  group by companyId
  having count(distinct statusId) = 1); 
编辑:如果您想包括那些也有1,18和18,1的人,那么您可以使用array_agg:

select *
from t t1
inner join
     (select companyId, array_agg(statusId) as statuses
      from t
      group by companyId
     ) t2 on t1.companyid = t2.companyid
where array[1,18] @> t2.statuses;
编辑:如果您打算只返回CompanyID,而不返回其余列和数据:

select companyId
      from t
      group by companyId
      having array[1,18] @> array_agg(statusId);

您可以通过和拥有使用group by。即:

select * 
from myTable 
where statusId in (1,18)
and companyId in (select companyId 
  from myTable 
  group by companyId
  having count(distinct statusId) = 1); 
编辑:如果您想包括那些也有1,18和18,1的人,那么您可以使用array_agg:

select *
from t t1
inner join
     (select companyId, array_agg(statusId) as statuses
      from t
      group by companyId
     ) t2 on t1.companyid = t2.companyid
where array[1,18] @> t2.statuses;
编辑:如果您打算只返回CompanyID,而不返回其余列和数据:

select companyId
      from t
      group by companyId
      having array[1,18] @> array_agg(statusId);

您可以
按公司ID分组
,并在
having
子句中设置2个条件:

select companyid
from tablename
group by companyid
having 
  sum((status in (1, 18))::int) > 0
  and
  sum((status not in (1, 18))::int) = 0
或与:

请参阅。
结果:


您可以
按公司ID分组
,并在
having
子句中设置2个条件:

select companyid
from tablename
group by companyid
having 
  sum((status in (1, 18))::int) > 0
  and
  sum((status not in (1, 18))::int) = 0
或与:

请参阅。
结果:


很抱歉,它不是那样存储的,这只是一个示例,每行有一个status值。很抱歉,它不是那样存储的,这只是一个示例,每行有一个status值。问题是,如果我有1和18的同伴,它将不会出现,因为它不会是计数的一部分。@karellahmy,我不清楚您是否只想得到(1)、(18)组或(1,18)以及。无论如何,在看到您的评论之前已经编辑过了。@karellahmy,顺便说一句,如果您只需要companyId而不需要其他列,只需要使用Having()子句的子查询。问题是,如果我有company with 1和18,它将不会出现,因为它不会是计数的一部分。@karellahmy,我不清楚您是否只想得到(1)、(18)组或(1,18)以及。无论如何,在看到您的评论之前已经编辑过了。@karellahmy,顺便说一句,如果您只需要companyId而不需要其他列,只需使用Having()子句的子查询即可。