嵌套选择中的 WHERE 子句

Posted

技术标签:

【中文标题】嵌套选择中的 WHERE 子句【英文标题】:WHERE clause in nested select 【发布时间】:2013-12-04 11:39:39 【问题描述】:

所以我在尝试对数据表执行嵌套选择时遇到了一点问题。

我在多个图书馆拥有大量书籍。每本书都有一个 ID,每个位置都有一个名称。每次出书或还书时,都会在事务表上记录一笔交易。

表格看起来有点像这样:

+---------+--------+----------+------------+
| BOOK_ID | IN_OUT | LOCATION |    DATE    |
+---------+--------+----------+------------+
| B01     | O      | RED      | 2013-10-04 |
| B02     | O      | BLUE     | 2013-10-04 |
| B01     | I      | RED      | 2013-10-19 |
| B01     | O      | RED      | 2013-10-20 |
| B02     | I      | RED      | 2013-10-21 |
| B01     | I      | BLUE     | 2013-10-24 |
+---------+--------+----------+------------+

(谢谢,@Senseful!)

现在,我可以显示所有交易及其 in_time、out_time 成对显示:

SELECT i.BOOK_ID
                  ,(SELECT MAX(o.DATE)
                      FROM TRANSACTIONS o
                     WHERE (o.IN_OUT = 'O')
                       AND o.BOOK_ID = i.BOOK_ID
                       AND o.DATE < i.DATE
               ) AS out_time
  , i.DATE AS in_time
  , LOCATION
  FROM TRANSACTIONS i
 WHERE i.IN_OUT = 'I'
 ORDER BY i.DATE
;

但是,现在我只想显示书籍被退回到不同位置的交易:所以在上面的示例中,我尝试选择 LOCATION 作为 out_location 以添加 WHERE 子句来检查是否它等于 in_location。

很公平:

,(SELECT MAX(o.DATE), LOCATION as out_location
                      FROM TRANSACTIONS o

没有办法。 “ORA-00913: too many values”。

对于像这样限制输出的最明智的方法有什么想法吗?

【问题讨论】:

您可以使用分析函数获得结果。以这个问题为例:***.com/questions/17824432/… 您可以将AND o.location &lt;&gt; i.location 添加到您的内部选择中,但这不会为您提供图书的当前位置。 @SQB 对,这看起来更有希望......评估正确,如预期的那样在out_time 上给我一个(null)。虽然在外部选择上添加where ... out_time is not null 会给出ORA-00904: "i"."out_time": invalid identifier - 那么不会'看到' out_time 列吗? 【参考方案1】:

分析函数非常适合此类查询。您可以使用LEADLAG 获取组中的上一行或下一行。

我为您创建了一个 SQLFiddle 示例:http://www.sqlfiddle.com/#!4/725c1/14

得到的选择语句是这样的:

select *
from (
   SELECT i.BOOK_ID
   , i.in_out
   , i.event_date AS in_time
   , LOCATION in_location
   , lag(event_date) over (partition by book_id order by event_date) out_date
   , lag(location) over (partition by book_id order by event_date) out_location
   FROM TRANSACTIONS i
   ORDER BY i.event_date)
where in_out = 'I'
and   in_location != out_location;

【讨论】:

太棒了。我现在还有另一件事要阅读……分析函数!谢谢@Alen。 这是我回来再次感谢你。我刚刚在另一种情况下使用了它,完全取代了我拥有的声明的庞然大物。这很漂亮。我感觉自己像个新人。生活是美好的。 嘿嘿,很高兴你喜欢。

以上是关于嵌套选择中的 WHERE 子句的主要内容,如果未能解决你的问题,请参考以下文章

在 Haskell 中使用嵌套的 `where` 子句

where 子句中的多项选择

PostgreSQL unnest,嵌套字段特定元素的 WHERE 子句

Rails:使用 where 子句查找深度嵌套的关联

sequelize 嵌套包含 where 子句

在嵌套结构中使用 where 子句