Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何使用多个条件进行查询,而这些条件不能仅在一行上匹配_Sql_Postgresql - Fatal编程技术网

Sql 如何使用多个条件进行查询,而这些条件不能仅在一行上匹配

Sql 如何使用多个条件进行查询,而这些条件不能仅在一行上匹配,sql,postgresql,Sql,Postgresql,我在这里提供了我目前正在使用的表的简化示例: 创建表格订单 id串行主键, 客户id INT, 创建于日期 ; 插入订单 客户标识,创建于 价值观 1, '2019-10-09', 1, '2019-10-01', 1, '2019-08-09', 2, '2019-10-09', 2, '2019-10-09', 3, '2019-09-09', 3, '2019-08-09', 4, '2019-08-09', 4, '2019-08-09', 5, '2019-10-09', 5, '20

我在这里提供了我目前正在使用的表的简化示例:

创建表格订单 id串行主键, 客户id INT, 创建于日期 ; 插入订单 客户标识,创建于 价值观 1, '2019-10-09', 1, '2019-10-01', 1, '2019-08-09', 2, '2019-10-09', 2, '2019-10-09', 3, '2019-09-09', 3, '2019-08-09', 4, '2019-08-09', 4, '2019-08-09', 5, '2019-10-09', 5, '2019-10-09', 5, '2019-08-09' ; 我的问题是,我只想返回在两个特定日期有一个或多个订单的客户,并且在这两个日期之间没有订单。在小提琴中,只有客户id为5的才应该匹配

在尝试了许多不同的查询方式之后,我终于找到了一种使用一组EXISTS子句的方法:

选择DISTINCTcustomer\u id 来自订单o1 如果存在,从订单o2中选择1,其中o1.customer_id=o2.customer_id,o2.created_at='2019-10-09' 并且存在从订单o2中选择1,其中o1.customer_id=o2.customer_id和o2.created_at='2019-08-09' 并且不存在从订单o2中选择1,其中o1.customer_id=o2.customer_id,o2.created_在“2019-08-10”和“2019-10-08”之间
但我想知道是否有一种更简单、更有效的方法可以做到这一点。

您可以使用条件聚合:

SELECT customer_id
FROM orders
WHERE created_at BETWEEN '2019-08-09' AND '2019-10-09'
GROUP BY customer_id
HAVING MIN(created_at) = '2019-08-09'
AND    MAX(created_at) = '2019-10-09'
AND    COUNT(DISTINCT created_at) = 2
HAVING子句将筛选具有匹配条件的组。

您可以按客户id分组,并在HAVING子句中设置条件:

看。 结果:

博士后有很好的表现

根据您的实际数据,查询速度应该比您的快一点或明显快一点。

不相关,但:distinct不是一个函数。它始终适用于“选择”列表中的所有列。用括号括住其中一列不会改变任何东西,也没有用。不同的a,b与不同的a,b或不同的a,b相同
SELECT customer_id 
FROM orders
GROUP BY customer_id
HAVING 
    SUM((created_at = '2019-10-09')::int) > 0
  AND 
    SUM((created_at = '2019-08-09')::int) > 0
  AND 
    SUM((created_at BETWEEN '2019-08-10' AND '2019-10-08')::int) = 0
| customer_id |
| ----------- |
| 5           |
select customer_id
from orders
where created_at between '2019-08-09' and '2019-10-09'
group by customer_id
having bool_or(created_at = '2019-10-09')
and bool_or(created_at = '2019-08-09')
and not bool_or(created_at between '2019-08-10' and '2019-10-08')