Oracle 形成SQL查询以跨行比较结果
问题陈述: 选择所有门店的名称、状态、电话号码、生效日期 其电话号码从2003年至今已更改 模式是Oracle 形成SQL查询以跨行比较结果,oracle,Oracle,问题陈述: 选择所有门店的名称、状态、电话号码、生效日期 其电话号码从2003年至今已更改 模式是 store_name,phone number , start_date , status 样本行 abc 1234 30-DEC-2011 open abc 3433 04-Jan-2012 close bbb 4444 30-Jan-2010 open bbb 4444 31-Jan-2011 open 输出 abc 1234 open 3
store_name,phone number , start_date , status
样本行
abc 1234 30-DEC-2011 open
abc 3433 04-Jan-2012 close
bbb 4444 30-Jan-2010 open
bbb 4444 31-Jan-2011 open
输出
abc 1234 open 30-DEC-3011 till 3-Jan-2012
abc 3433 close 04-Jan-2012 till date
我还可以在输出中使用两行排序的开始日期,如
abc 1234 30-DEC-2011 open
abc 3433 04-Jan-2012 close
bbb
不应报告,因为电话号码没有变化。我们应该只报告那些电话号码已更改的商店
有人能帮我查询一下Oracle吗?我想通过使用相关查询可以做到这一点,但我不确定如何构建一个相关查询
请注意,我的表大约有3154953条记录,因此我还需要确保关联查询不会在整个时间段内锁定表。甲骨文有可能做到这一点吗
谢谢
APC的答案对我来说很有用,因为我在结果中看到了很多重复 输入:
select store_name,phone_number,start_date, status where store_name=abc;
返回
STORE_name Phone number start_date STATUS
---------------- ---------------- ----------- ----------
abc 122 18-JAN-2011 open
abc 122 18-JAN-2011 open
abc 122 18-JAN-2011 close
运行查询会得到以下输出
abc 122 open from 18-JAN-2011 to 17-JAN-2011
abc 122 open from 18-JAN-2011 to 17-JAN-2011
abc 122 close from 18-JAN-2011 to date
你能解释一下小姐为什么在哪里吗?这将是一个大致相同的问题
select * from table0 as q0 join
(
select min(date) from table0 as q1 where q1.store_name = q0.store_name
) as q2 on q2.store_name = q0.store_name
left join
(
select max(date) from table0 as q1 where q1.store_name = q0.store_name
) as q3 on q3.store_name = q0.store_name
这并不完全正确,因为我面前没有MySQL,但大致上是这样的。我认为这是针对Oracle而不是MySQL的,因为我的解决方案使用了一些我很确定在MySQL中不可用的魔术。第一个是公共表表达式,用于获取可以多次使用的结果集。第二个是使用LEAD()分析函数“预测”下一行的值 因此,问题是:
with a as ( select store_name
, phone_number
, status
, start_date
, lead (start_date, 1, trunc(sysdate)) over (partition by store_name
order by start_date) as next_date
, lead (phone_number, 1, null) over (partition by store_name
order by start_date) as next_number
from your_table
where start_date >= date '2003-01-01' )
select a.store_name
, a.phone_number
, case when a.next_date != trunc(sysdate) then
a.status||' from '|| a.start_date ||' to '||to_char(a.next_date - 1)
else a.status||' from '||a.start_date ||' to date'
end as status_text
from a
where a.store_name in (
select store_name
from a
where phone_number != next_number)
order by a.store_name, a.start_date
/
这是它的输出:
SQL> r
1 with a as ( select store_name
...
22 order by a.store_name, a.start_date
23 /
STORE_NAME PHONE_NUMBER STATUS_TEXT
-------------------- ------------ --------------------------------
abc 1234 open from 30-DEC-11 to 03-JAN-12
abc 3433 close from 04-JAN-12 to date
2 rows selected.
SQL>
关于这句话:
“因此,我还需要确保相关查询不会锁定
“整批时间表”
在Oracle中不重要,因为读取不会阻止其他读取。也没有写过这样的内容。@ManseUK-您删除了[mysql]标记,并忽略了标题中对mysql的引用。在开始编辑之前,请确保您的更改不会扭曲OP的意图。@APC抱歉。。。这是我今天犯的两个编辑错误。。。。添加标签回到。。。尽管我真的不知道为什么它会出现在标题或标签中?@TopCoder-“我看到很多重复……你能解释一下原因吗?”。您的数据包含大量重复。重复的输入会产生重复的输出,这并不奇怪,是吗?至于结束日期的奇怪之处,我的查询期望记录之间有一天的宽限期。如果您真的有这样古怪的业务逻辑,那么您必须定制查询来处理它们。谢谢!它工作得很好。我还得到了一个阅读lead函数的机会。我看到了结果中的一些问题。我编辑了这个问题,你能调查一下,让我知道我遗漏了什么吗?