Avatar billede tbm_iceman Nybegynder
18. oktober 2004 - 10:50 Der er 11 kommentarer og
1 løsning

Random RS + Sandsynlighed

Hej Eksperter.

Jeg har 2 tabeller.

T:Series
  `ID` int(11) NOT NULL auto_increment
  `Name` varchar(64) NOT NULL default '',
  `Description` varchar(500) NOT NULL default '',
  PRIMARY KEY (`ID`)

T:Picture
  `ID` int(11) NOT NULL auto_increment
  `FileName` varchar(64) NOT NULL default '',
  `SerieID` int(64) NOT NULL default 0,
  PRIMARY KEY (`ID`),
  FOREIGN KEY (`SerieID`) REFERENCES `Series`(`ID`)

Det jeg gerne vil er at lave et recordset med 10 random valgte billeder fra "Picture" af.
Men jeg vil have den til at vælge billederne med disse sandsyneligheder:
  40% chance for at billederne er fra de sidste to "Series".
  60% chance for at billederne er fra all andre "Series".

Billederne må kun kunne vælges engang.

Jeg kan sagtens få det til at fungere med "ORDER BY Rnd(-(ID))"
men der har jeg ikke sandsynelighederne med så det er ikke så godt.
Jeg har tænkt lidt over noget med UNION?

//IceMan
Avatar billede ldanielsen Nybegynder
18. oktober 2004 - 12:53 #1
Utestet:

SELECT TOP 10 * FROM
(

SELECT TOP 40 Picture.ID FROM
Picture INNER JOIN Series ON Picture.SerieID = Series.ID WHERE Series.ID IN (SELECT TOP 2 ID FROM Series ORDER BY ID DESC)
ORDER BY NEWID()

UNION

SELECT TOP 60 Picture.ID FROM
Picture INNER JOIN Series ON Picture.SerieID = Series.ID WHERE Series.ID NOT IN (SELECT TOP 2 ID FROM Series ORDER BY ID DESC)
ORDER BY NEWID()

) tempTable
ORDER BY NEWID()
Avatar billede ldanielsen Nybegynder
18. oktober 2004 - 13:00 #2
Lidt betænkeligheder:

Hvis der ikke er 40 hhv 60 af de ønskede billeder, vil sandsynligheden ikke være korrekt. Man kunne naturligvis selecte TOP 4 hhv TOP 6, men så ville man få 10 billeder hvoraf de 4 altid ville være fra nye serier osv.

Så vidt jeg kan se ville TOP 10 hhv TOP 15 være nok, brug det i stedet for 40 og 60
Avatar billede tbm_iceman Nybegynder
18. oktober 2004 - 15:18 #3
ahh... Nice solution, but won't this be a database killer?
Avatar billede tbm_iceman Nybegynder
18. oktober 2004 - 15:20 #4
Tror jeg arbejder for meget for udlandet. :P
Avatar billede ldanielsen Nybegynder
18. oktober 2004 - 15:41 #5
Næ, det tror jeg ikke ...

Jeg skræller lige noget unødvendigt fra:


SELECT TOP 10 * FROM
(

SELECT TOP 10 Picture.ID FROM
Picture INNER JOIN Series ON Picture.SerieID = Series.ID WHERE Series.ID IN (SELECT TOP 2 ID FROM Series ORDER BY ID DESC)

UNION

SELECT TOP 15 Picture.ID FROM
Picture INNER JOIN Series ON Picture.SerieID = Series.ID WHERE Series.ID NOT IN (SELECT TOP 2 ID FROM Series ORDER BY ID DESC)

) tempTable
ORDER BY NEWID()

Der behøver kun at komme ORDER BY NEWID() til sidst

Hvis vi tager den "udefra", så er top 10 from <<25 rækker>> ORDER BY NEWID() i hvert fald ikke tung. Heller ikke UNION af samme 25 rækker.

Det der er tungest er nok subquery'en efter NOT IN, men den bliver jo resolved først. Man kunne lave den om til WHERE ID < (SELECT MIN(ID) FROM (SELECT TOP 2 ID FROM Series ORDER BY ID DESC) temptable2)  .. eller sådan noget

Men virker den så efter hensigten?
Avatar billede tbm_iceman Nybegynder
18. oktober 2004 - 15:49 #6
Har ikke testet det endnu. Gør jeg senere i dag. Men det ser meget godt ud.
Avatar billede tbm_iceman Nybegynder
18. oktober 2004 - 15:55 #7
Når du laver en ORDER BY NEWID() ... det er da ikke en unik random rækkefølge er det?
Avatar billede ldanielsen Nybegynder
18. oktober 2004 - 20:46 #8
Jo det er.

NEWID() genererer en uniqueidentifier, dvs. enoget der ligner 6F9619FF-8B86-D011-B42D-00C04FC964FF. Og der kommer "aldrig" to ens.

Prøv at skrive
SELECT NEWID()

eller
SELECT ID, NEWID() FROM Series

Så vil du se det
Avatar billede tbm_iceman Nybegynder
19. oktober 2004 - 15:26 #9
Det virker sådant næsten.

Men du skal have NEWID() på de to første for ellers tager den jo altid bare de 10/15 billeder med de højeste ID.

Men hvis dette skulle laves i Access og du ikke har NEWID hvad kan jeg så lige gøre?

Derud over får jeg at vide konstant at jeg kun kan sætte ORDER BY på den først Union query.

Her er hvad jeg prøver pt:

SELECT TOP 4 ID,SerieID,FileName,Folder FROM
(

SELECT TOP 15 P.ID,P.SerieID,P.FileName,S.Folder FROM
Pictures P INNER JOIN PicSeries S ON P.SerieID = S.ID WHERE S.ID IN (SELECT TOP 2 ID FROM PicSeries ORDER BY ID DESC) ORDER BY Rnd(-P.ID*" & R1 & ")

UNION

SELECT TOP 10 P.ID,P.SerieID,P.FileName,S.Folder FROM
Pictures P INNER JOIN PicSeries S ON P.SerieID = S.ID WHERE S.ID NOT IN (SELECT TOP 2 ID FROM PicSeries ORDER BY ID DESC)

) TmpTable
ORDER BY Rnd(-(ID*" & R3 & "))
Avatar billede ldanielsen Nybegynder
19. oktober 2004 - 15:40 #10
Hvis det er MS-SQL ville jeg måske gemme to views med de to dele, og så bruge dem, så ville du få lov til at bruge order by.

Det kan også laves direkte med parenterer og alias'er, kan ikke lige lave det nu ...

Access, tja ...
Avatar billede tbm_iceman Nybegynder
20. september 2010 - 21:25 #11
Lukker spm.
Avatar billede tbm_iceman Nybegynder
20. september 2010 - 21:26 #12
Lukker spm.
Avatar billede Ny bruger Nybegynder

Din løsning...

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.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester