18. april 2005 - 17:09Der er
11 kommentarer og 1 løsning
Selecte de mest aktuelle artikler
Jeg er rimelig ny til MSSQL (har tidligere brugt MySql), og er lidt i tvivl om hvilke muligheder man faktisk har i stored procedures.
I et system jeg arbejder med har jeg følgende tabel:
Articles ---------- articleID (varchar) title (nvarchar) body (ntext) start (datetime) end (datetime)
Følgende problem skal løses - er det muligt som en stored procedure? (hvis ja: hvordan?)
- Metoden skal gerne kunne kaldes med en numerisk værdi som paramter der fortæller hvor mange rækker der skal hentes (TOP x). - Såfremt der findes artikler hvor (start < GETDATE() AND end > GETDATE()) skal disse selectes først. - Er der ikke aktuelle artikler nok, skal der "fyldes op" med artikler der har (start = NULL AND end = NULL)
Jeg kan godt følge det du skriver, men der er stadig nogle ting jeg er i tvivl om. Glemte forresten at skrive at de (start = NULL AND end = NULL) artikler der hentes, meget gerne skal være random på en eller anden måde.
For overskuelighedens skyld ville det måske være det letteste at lave to views på tabellen - et med "nyheder" (altså de tidsindstillede), og et med de andre?
Måske er det den bedste løsning hvis jeg har en stored procedure der henter alle aktuelle nyheder, og en anden der giver mig x antal tilfældige artikler. På denne måde kunne jeg lade programmet der skal ligge oven på (C#) vurdere om der er nyheder nok, og hvis der ikke er det bede om nogle tilfældige artikler.
At selecte en random row kan godt være lidt besværligt, det vigtige er jo at de id's som random giver tilbage rent faktisk også findes i tabellen. Det kan løses på forskellige måder, her er eks.vis en:
For at begrænse resultatet lidt kan man måske nøjes med at vælge random indenfor måneden/ ugen osv... kommer an på antallet af dine artikler.
select id, identity(int, 1, 1) as iid into #rand_id from Articles where startdate < getdate() - 30
Find max og min iid fra tabellen! Herefter laver du en random: select @rand_id = rand() * maxID , dette iid findes i #rand_id
Nu kan du så lave en join på det op imod dine Articles
select * from Articles a inner join #rand_id r on r.id = a.id where r.iid = @rand_id
Hvis du vil have flere random artikel id's, så kunne du evt. select rand() * maxID as rand_id into #rand_id declare @i int set @i = 0 while @i < 5 begin insert into #rand_id select rand() * maxID set @i = @i + 1 end
Og herefter joine op imod denne også. Som du kan se er sådan en random lidt besværlig at arbejde med. Jeg har flere gange også rådet folk til at generere en tabel en gang i døgnet og så altid bruge den som reference tabel, istedet for at lave en mapping imellem fortløbende id'er og id fra sourcetable... Der er mange muligheder.. håber det har hjulpet dig lidt på vej :O)
Jeg har skam en ID, det er bare ikke fortløbende numerisk, men derimod en varchar. Årsagen er at der i det webinterface der skal på, gerne skal kunne vises nogle pæne URL's - fx www.mitsite/articles/celebration.html, hvor "celebration" er ID på en artikel.
Hvis det er nødvendigt for at kunne lege med random, må jeg vel blot lave en ekstra kolonne med fortløbende numre.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.