嵌套选择中的 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 <> i.location
添加到您的内部选择中,但这不会为您提供图书的当前位置。
@SQB 对,这看起来更有希望......评估正确,如预期的那样在out_time
上给我一个(null)
。虽然在外部选择上添加where ... out_time is not null
会给出ORA-00904: "i"."out_time": invalid identifier
- 那么不会'看到' out_time 列吗?
【参考方案1】:
分析函数非常适合此类查询。您可以使用LEAD
或LAG
获取组中的上一行或下一行。
我为您创建了一个 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 子句的主要内容,如果未能解决你的问题,请参考以下文章