2016-03-31 2 views
0

bin bei Punkt fest, um die Logik aufzubauen. Kann mir jemand helfen ?Logik, um nur eine Zeile in der Ergebnismenge zu erhalten

Anforderung:

Für privacyType = 'Primary Address', wenn es> 1 Zeile, in SI0_ADDR.ADDR_TYPE_CODE = 'M', die Zeile angezeigt, in dem current() zwischen SI0_ADDR.ADDR_EFF_DATE und SI0_ADDR.ADDR_EXPR_DATE ist.

meine Frage ist:

select STU_ID 
     ,case when Privacyflag = '' then 'N' 
      else Privacyflag 
     end Privacyflag 
     ,type from (
select a.STU_ID,Privacyflag,a.type 
    ,ROW_NUMBER() OVER (ORDER BY ADDR_EXPR_DATE DESC) disp_nm from (
select ad.STU_ID, case when ad.ADDR_TYPE_CODE = 'M' then ad.ADDR_PRIVACY_FLAG 
         when ad.ADDR_TYPE_CODE='' then 'N' 
        end Privacyflag, 'Primary Phone' type 
       , case when ADDR_EXPR_DATE = '1900-01-01' then '2100-12-31' 
         else ADDR_EXPR_DATE 
       end as ADDR_EXPR_DATE 

from SI0_ADDR ad 
where ad.STU_ID = @studentid) a 
where Privacyflag is not null 
) ab 
where ab.disp_nm = '1' 

Diese Logik nicht in einigen Fällen arbeitet

+2

Bitte folgen Sie den Buchungsrichtlinien in der Hilfe. [Minimales, vollständiges, überprüfbares Beispiel] (http://stackoverflow.com/help/mcve) gilt hier. "In einigen Fällen nicht funktionieren" ist keine Problembeschreibung. – Prune

+0

Wo ist 'Primäradresse' in Ihrer Abfrage? Ich sehe nicht, wo du es benutzt hast – FLICKER

Antwort

0

Sie sind nicht durch das Datum in irgendeiner Weise einzuschränken, die einen Teil Ihrer Anforderungen war. Ihre Abfrage benötigt nicht so viele verschachtelte Unterabfragen. Die PrivacyFlag scheint nicht Teil Ihrer Frage zu sein, also habe ich es in diesem Beispiel nicht bearbeitet. Und Ihr Beispiel zeigt Primary Phone, aber Ihre Frage spricht über Primary Address, so dass ich nicht sicher bin, wie das funktioniert.

In jedem Fall ist hier ein sehr einfaches Beispiel, das die Daten zeigt, und wie den eine Datensatz mit dem neuesten Ablaufdatum und auch die neuesten Stichtag (in Fall gibt es zwei Datensätze mit demselben ziehen Haltbarkeitsdatum).

create table #temp (stu_id int, type varchar(10), address varchar(50), eff_date datetime, expr_date datetime) 

insert into #temp values 
(1, 'primary', '123 NW 52nd', '1/1/2016', '1/1/1900'), 
(1, 'primary', '942 SE 33rd', '1/2/2016', '12/31/2016'), 
(1, 'primary', '721 SW 22nd', '4/1/2015', '1/1/1900') 

select top 1 * 
from (
     select stu_id 
       ,type 
       ,address 
       ,eff_date 
       ,case when expr_date = '1/1/1900' then '12/31/2100' else expr_date end as expr_date 
     from #temp 
     where stu_id = 1 
      and type = 'primary' 
     ) as a 
where getdate() between eff_date and expr_date 
order by a.expr_date desc, a.eff_date desc 

drop table #temp 

Sie könnten sogar mit Null Unterabfragen es tun, aber dann würden Sie müssen die case Anweisung in die where und order by Teile der Abfrage duplizieren:

select top 1 
     stu_id 
     ,type 
     ,address 
     ,eff_date 
     ,case when expr_date = '1/1/1900' then '12/31/2100' else expr_date end as expr_date 
from #temp 
where stu_id = 1 
    and type = 'primary' 
    and getdate() between eff_date and case when expr_date = '1/1/1900' then '12/31/2100' else expr_date end 
order by case when expr_date = '1/1/1900' then '12/31/2100' else expr_date end desc 
     ,eff_date desc 

Mit einem so kleinen Datensatz, der showplan nicht angibt, welche Abfrage am effizientesten wäre; Es zeigte denselben identischen Abfrageplan für beide Abfragen, außer dass die erste select-Anweisung sieben CPU-Zyklen benötigte, um den Plan zu kompilieren, und die zweite select-Anweisung zwei CPU-Zyklen benötigte, um den Plan zu kompilieren. Sie möchten vielleicht einen größeren Datensatz in realen Tabellen mit Indizes usw. testen und sehen, welcher der beste ist.