2012-01-05 2 views
0

Énoncé du problème:La formation d'une requête SQL pour comparer les résultats entre les lignes

sélectionner tous les noms de magasins, leur statut, les numéros de téléphone, date dont le numéro a été changé à partir de 2003 jusqu'à la date actuelle.

schéma est

store_name,phone number , start_date , status 

rangées d'échantillons

abc 1234 30-DEC-2011 open 
    abc 3433 04-Jan-2012 close 
    bbb 4444 30-Jan-2010 open 
    bbb 4444 31-Jan-2011 open 

de sortie

abc 1234 open 30-DEC-3011 till 3-Jan-2012 
    abc 3433 close 04-Jan-2012 till date 

Je suis aussi très bien avoir deux lignes en sortie avec date de début triés comme

abc 1234 30-DEC-2011 open 
abc 3433 04-Jan-2012 close 

bbb ne doit pas être signalé car il n'y avait pas de changement de numéro de téléphone. Nous ne devons indiquer que les magasins pour lesquels le numéro de téléphone a été modifié.

Quelqu'un peut-il m'aider avec cette requête sur Oracle? Je suppose qu'en utilisant des requêtes corrélées cela peut être fait mais je ne suis pas sûr comment je peux en construire un.

Veuillez noter que ma table a environ 3154953 enregistrements, donc je dois également m'assurer que la requête corrélée ne verrouille pas la table pendant tout le temps. Est-ce même possible avec Oracle?

Merci!


La réponse d'APC fonctionne pour moi juste que je vois beaucoup de répétitions dans mon résultat.

Pour l'entrée:

select store_name,phone_number,start_date, status where store_name=abc; 

retours

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 

l'exécution de votre requête me donne la sortie suivante.

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 

Pouvez-vous expliquer pourquoi et où est le miss?

+1

Est-ce que c'est pour MySQL ou Oracle? –

+0

@ManseUK - vous avez supprimé la balise [mysql] et ignoré la référence à MySQL dans le titre. Assurez-vous que vos modifications ne fausseront pas les intentions du PO avant de commencer à éditer. – APC

+0

@ APC excuses ... c'est 2 erreurs d'édition ive fait aujourd'hui .... tag ajouté dans ... bien que je ne sais vraiment pas pourquoi c'est dans le titre ou étiqueté? – ManseUK

Répondre

2

Je présume que c'est pour Oracle plutôt que pour MySQL, car ma solution utilise quelques astuces magiques dont je suis certain qu'elles ne sont pas disponibles en MySQL. La première est l'expression de table commune pour obtenir un ensemble de résultats que nous pouvons utiliser plus d'une fois. La seconde est l'utilisation de la fonction analytique LEAD() pour "prédire" les valeurs dans la rangée suivante.

Alors, voici la question:

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 
/

Et voici sa sortie:

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> 

En ce qui concerne cette remarque:

« donc je dois aussi faire en sorte que corrélée la requête ne verrouille pas le tableau pour tout le temps "

N'importe pas dans Oracle, car les lectures ne bloquent pas les autres lectures. Ni écrit à venir à cela.

+0

Merci! ça fonctionne très bien. J'ai également eu l'occasion de lire sur la fonction de plomb. – TopCoder

+0

Je vois quelques problèmes avec le résultat. J'ai édité la question, pouvez-vous regarder s'il vous plaît et laissez-moi savoir ce que je manque? – TopCoder

0

Ce sera quelque chose le long des lignes de

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 

Ce n'est pas tout à fait raison que je n'ai pas MySQL en face de moi, mais ses quelque chose le long de ces lignes.

Questions connexes