所以我在一个嵌套选择上遇到了一些问题,我试图在数据表上做。
我有很多图书馆的书籍。每本书都有一个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
”。
关于限制输出的最合理方式的任何想法都是这样的吗?
答案 0 :(得分:1)
分析函数非常适合此类查询。您可以使用LEAD
或LAG
来获取组中的上一行或下一行。
我为您创建了一个SQLFiddle示例:http://www.sqlfiddle.com/#!4/725c1/14
生成的select语句是:
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;