用于评估多行的 SQL 查询

Posted

技术标签:

【中文标题】用于评估多行的 SQL 查询【英文标题】:SQL Query to evaluate multiple rows 【发布时间】:2013-06-21 22:06:06 【问题描述】:

我只想从订单表中检索已支付所有订单的客户。 (付费 = 'Y')。

订单表如下所示:

Cus #     Order #    Paid 
111            1        Y 
111            2        Y
222            3        Y
222            4        N
333            5        N

在本例中,查询应该只返回客户 111。

查询

Select * from order where Paid = 'Y';

返回已支付和未支付订单的客户(例如客户 222)以及已支付所有订单的客户(客户 111)。

如何构建查询以评估客户的所有订单并仅返回已为所有订单付款的客户的信息?

【问题讨论】:

付费列的可能值是否超过三个?如果不是,您应该使用布尔数据类型,而不是字符串。 【参考方案1】:

换个角度看问题,您只需要没有任何未付款订单的客户。

sel cus from order group by Cus having min(Paid) = 'Y';

上述查询还利用了'Y' > 'N'这一事实。

SQL 小提琴:

http://sqlfiddle.com/#!4/f6022/1

如果您需要为符合条件的客户选择所有不同的订单,您可以使用 OLAP 函数:

select cus,order,paid from (select cus,order,paid,min(paid) 
                over (partition by cus)minz from order)dt where minz='Y';

【讨论】:

【参考方案2】:

使用 Oracle,您也可以使用 select customer from your_table where paid='Y' minus select customer from your_table where paid='N',虽然我不知道这是否更快,当然,在这种情况下您不会获得其他字段。

【讨论】:

【参考方案3】:

不了解Oracle,但经常在SQL Server中工作,我会写这样的查询

Select Cus from order group by Cus having count(*) = sum(case when Paid = ‘Y’ then 1 else 0);

基本上,您会检索总订单数等于总订单数或已付款订单的客户。

再次,为没有提供正确的 Oracle 语法而道歉,但希望这将为您指明正确的方向。

【讨论】:

【参考方案4】:
SELECT  *
FROM    orders oo
WHERE   NOT EXISTS
        (
            SELECT  1
            FROM    orders io
            WHERE   oo.cus# = io.cus#
            AND     io.paid = 'N'
        )
;

【讨论】:

子查询不是必需的,这里推荐..请确保仅在必要时使用子查询..!! 它与“Select * from”一起工作,这就是为什么它是必要的。 “EXISTS”并不总是必需的,但通常是推荐的。 任何 subq 方法都会增加处理时间,想想表包含数百万行的情况。 OP 没有提到他是否需要具有不同 order# 值的所有列。无论如何,可以通过使用PLAP>来实现

以上是关于用于评估多行的 SQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

SQL 查询优化的短路评估

SQL查询成本的理论评估

使用 PHP PDO 在 SQL 中将多行传递给 UDF

SQL 查询的 SELECT 子句中 Oracle PL/SQL 语句的延迟评估

SQL 编译错误:无法评估不受支持的子查询类型 - SELECT 子句中的函数调用

针对 LINQ To SQL 查询中的位字段评估布尔值