Frage

Ich versuche zur Bestimmung einer SMS-Nachricht einer Lookup-Methode zu schreiben, um einen Benutzer auf wenigen Parametern mit dem Benutzer / System zugeordnet Basis zu senden. Wir werden eine Standardnachricht, die als letztes Mittel eingesetzt werden, aber es gibt mehr Möglichkeiten, um die Nachricht durch verschiedene Parameter außer Kraft zu setzen. Hier ist, was ich bisher für die Suche Abfrage habe - ist es bessere Möglichkeiten, dies zu tun? Vielleicht ein Nachschlag ist nicht der richtige Ansatz für das?

Hier ist die Lookup-Tabelle:

MessageLookup
{
ID bigint PK                          
Key varchar                           
CampaignTypeID bigint FK,             
ServiceProviderID bigint FK nullable, -- optional override parameter
DistributorID bigint FK nullable,     -- optional override parameter
CampaignID bigint FK nullable,        -- optional override parameter
Message varchar                   
}

Hier ist ein Beispiel dafür, was die Tabelle aussehen würde:

   ID Key  CTID SPID DistID CampID Message
    1 Help 1    NULL NULL   NULL   'This is the default message'
    2 Help 1    375  NULL   NULL   'This is the SP375 message'
    3 Help 1    377  NULL   NULL   'This is the SP377 message'
    4 Help 1    NULL 13     NULL   'This is the Dist13 message'
    5 Help 1    375  13     NULL   'This is the SP375/Dist13 message'
    6 Help 1    NULL 13     500    'This is the Dist13/Camp500 message'
    7 Help 1    375  13     500    'This is the SP375/Dist13/Camp500 msg'
    8 Help 1    NULL NULL   500    'This is the Camp500 help message'

Hier ist die Abfrage ich habe:

select
    --top 1
    *
from MessageLookup ml
where ml.[Key] = @Key
and ml.CampaignTypeID = @CampaignTypeID
and
(
    ml.ServiceProviderID = @ServiceProviderID or
    ml.ServiceProviderID is null
)
and
(
    ml.DistributorID = @DistributorID or
    ml.DistributorID is null
)
and
(
    ml.CampaignID = @CampaignID or
    ml.CampaignID is null
)
order by
    CampaignID desc, -- highest precedence lookup param
    DistributorID desc,
    ServiceProviderID desc -- lowest precedence lookup param
War es hilfreich?

Lösung

Ich bin mir nicht sicher, was der beste Weg ist, aber hier sind einige Alternativen:

Ein Gedanke wäre ein Muster zu speichern, mit jeder Regel, etwa so:

ID Key CTID Rule        Message
1 Help 1    '[%:%:%]'    'This is the default message'
2 Help 1    '[375:%:%]'  'This is the SP375 message'
3 Help 1    '[377:%:%]'  'This is the SP377 message'
4 Help 1    '[%:13:%]'   'This is the Dist13 message'
5 Help 1    '[375:13:%]' 'This is the SP375/Dist13 message'

und dann einen LIKE-Test anstelle allen ANDs.

Ein anderer Gedanke wäre die Verwendung von Outer-Joins.

oder (Ausspielen die Antwort, die gerade hereinkam) Dinge vertrocknen weiter durch Schreiben:

where ml.[Key] = @Key
  and ml.CampaignTypeID = @CampaignTypeID
  and IsNull(ml.ServiceProviderID = @ServiceProviderID,true)
  and IsNull(ml.DistributorID     = @DistributorID,    true)
  and IsNull(ml.CampaignID        = @CampaignID,       true)

Andere Tipps

Ich denke, das ist ein gültiger Ansatz, einfach zu erweitern, Absicht ziemlich klar ist, und Sie können die SQL ordentlich, indem Sie die folgenden

select
    --top 1
    *
from MessageLookup ml
where ml.[Key] = @Key
and ml.CampaignTypeID = @CampaignTypeID
and ml.ServiceProviderID = IsNull(@ServiceProviderID, ml.ServiceProviderID)
and ml.DistributorID = IsNull(@DistributorID, ml.DistributorID)
and ml.CampaignID = IsNull(@CampaignID, ml.CampaignID)
....

Was Sie tun, macht Sinn, und arbeitet. Wenn Sie nach Best Practices sind - nicht „SELECT *“ verwenden -. Aufzuzählen, welche Spalten Sie die Auswahl

Ich glaube, ich würde die Datenbank in einer anderen Art und Weise entwerfen, mit einem Tisch TA das wäre (MSGID, Schlüssel, CTID, Message) und eine weitere TB, die gespeichert werden sollten (MSGID, ID, IDTYPE) wobei ID darstellen würde Campid / DISTID / DefaultId (durch IDTYPE angegeben), sollte die PK von denen (ID, IDTYPE, MSGID) in dieser Reihenfolge sein. Sie können einen numerischen Wert zuzuweisen, um IDTYPE die Priorität, mit 0 für den Standard anzeigt (und einer passenden ID von 0). Alle Spalten sind NOT NULL.

Wenn ich gut Ihr Problem zu verstehen, wird Ihre Eingabe von drei Werten x gemacht, y und z (plus eine implizite 0 in meinem Fall), den Sie die Nachricht zurück, für die die meisten Spiele haben, und für den Fall, die Gleichheit, um durch IDTYPE.

select MSGID, count(*) as nbr_candidates, max(IDTYPE) as priority
from TB
where (ID = x and IDTYPE = ...)
   or (ID = y and IDTYPE = ...)
   or (ID = z and IDTYPE = ...)
   or (ID = 0 and IDTYPE = 0)
group by MSGID
order by 2 desc, 3 desc

sollte die „beste Nachricht“ als erste Zeile zurückgeben, und alles, was Sie brauchen, ist ein

top 1

dann mit der anderen Tabelle verbinden. Dies ist wahrscheinlich schneller sein als eine Ein-Tisch-Lösung, weil Tabelle TB nur numerisches IDs enthält und sehr kompakt sein, und die Verbindung wird sofort sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top