SQL-当一列有一个列表中的值和一个不在同一列表中的值时

SQL-当一列有一个列表中的值和一个不在同一列表中的值时,sql,postgresql,amazon-redshift,Sql,Postgresql,Amazon Redshift,我不确定用什么方法来表达这个问题,但我正在寻找一种方法来指定一个条件,当一列中的值在给定列表中至少有一个值,并且avalue不在同一列表中时,该列的值应该显示出来。示例表: email program john@john.com program1 john@john.com program2 john@john.com program3 jeff@jeff.com program3 jeff@jeff.com program4 steve@steve.co

我不确定用什么方法来表达这个问题,但我正在寻找一种方法来指定一个条件,当一列中的值在给定列表中至少有一个值,并且avalue不在同一列表中时,该列的值应该显示出来。示例表:

email           program
john@john.com   program1
john@john.com   program2
john@john.com   program3
jeff@jeff.com   program3
jeff@jeff.com   program4
steve@steve.com program1
steve@steve.com program2
如果我有这个表和一个program1,program2的列表,我想显示相应的电子邮件,如果与给定电子邮件关联的程序与给定列表中的至少一个相匹配,并且如果给定电子邮件有一个不在给定列表中的程序

因此,对于上面的表和给定的列表,我们将显示正确的查询:

email
john@john.com
having sum( (program in ('program1', 'program2'))::int ) > 0 and
       sum( (program not in ('program1', 'program2'))::int ) > 0;
在此方面的任何帮助都将不胜感激。注意:这将是在Redshift/PostgreSQL中,我喜欢使用group by和having来完成。以下是一个相当普遍的方法:

select email
from t
group by email
having sum( (program = 'program1')::int ) > 0 and
       sum( (program = 'program2')::int ) = 0;
在这种情况下,program1是必需的,program2不是。而且,您可以不断添加条件—任意数量

我忘了红移是否支持::语法。您始终可以使用标准SQL来表示这一点:

having sum( case when program = 'program1' then 1 else 0 end ) > 0 and
       sum( case when program = 'program2' then 1 else 0 end ) = 0;
编辑:

我认为@dnswit对OP问题的解析是正确的。逻辑是:

email
john@john.com
having sum( (program in ('program1', 'program2'))::int ) > 0 and
       sum( (program not in ('program1', 'program2'))::int ) > 0;

首先,您的数据表构造错误,您应该使用唯一标识符,以便可以检索您指定的程序版本

因此,您的数据库应如下所示:

> email           program1      program2       program3 
  john@john.com   ProgVersion1  ProgVersion2   ProgVersion3 
  steve@steve.com ProgVersion1  ProgVersion2   ProgVersion3
如果您注意到上面的表格,现在可以查询以获取指定电子邮件所需的程序值。使用SQL查询,表的数据字段为电子邮件,程序1程序2程序3,检索要显示的字段值时,您使用的是冗余,不需要为每个版本的程序重复多次电子邮件地址。这不是预期的方法

可以使用的SQL查询:

说明:您将创建一个参数,用作从列表中查询数据表的变量

> CREATE PROCEDURE spLoadMyProgramVersion
> 
> @email nvarchar(50),
> 
> AS 
>
>BEGIN 
>SELECT program1,program2,program3
>FROM  MyTableName 
>WHERE (email LIKE @email) RETURN

这将允许您在列表中加载所有程序版本,只需指定要加载的电子邮件地址,这是一个正在加载的存储过程,只要在创建SQLCommand对象时使用它,您就可以调用您的存储过程。

如果您只需要一个电子邮件列表,无论它们通过多个程序在列表中出现多少次
只是从tablename中选择不同的电子邮件

redshift或postgres?请删除不相关的标签?答案基于您提问的方法,而不是您使用的软件。这是一个简单的查询示例,可以根据尝试使用表的方法完成需要完成的操作。此外,它基于SQL queyOk,如果数据库不同,则SQL方法应相对相同,因为SQL查询可用于各种数据库。我的回答是,您应采用正确的方法。您的表应以易于查询的格式构造。我确信,这并不局限于任何特定的数据库。当为数据库或表和列表编程时,您应该知道该方法是一种通用的编程方法,无论您使用的数据库的版本或类型是什么,都应该是通用的。了解编程是如何应用的。例如,他给了我一个示例表,所以我应该告诉他如何构造他的表,这是一种方法,第二,我给了他一些SQL示例,也许这个示例适合另一个数据库,但是SQL方法可以以类似的方式呈现给他需要使用编程的数据库,因此如果你可以阅读SQL,那么他应该理解如何按照他的程序需要的方式构造SQL方法。简单的说,它应该遵循套件的要求,并为他所需要的服务。它所服务的数据库是Microsoft Sql Server。OP发布的问题是关于红移的,而不是Microsoft Sql Server。由于语法的原因,这个答案可能会让OP感到困惑,但可能有一些好主意。我认为OP想要所有包含program1或program2以及其他程序(如program3)的电子邮件。所以having条件应该是sum程序位于'program1','program2'::int>0,sum程序不在'program1','program2'::int>0:@dnswlt。我想你对这个问题的理解比我好一点。对于动态列表检查,技术将类似,只是基于与项目列表的完全连接