Oracle 形成SQL查询以跨行比较结果

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

问题陈述:

选择所有门店的名称、状态、电话号码、生效日期 其电话号码从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 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函数的机会。我看到了结果中的一些问题。我编辑了这个问题,你能调查一下,让我知道我遗漏了什么吗?