webForumDet fria alternativet

Hämta ut så länge summan är under 100

Databaser & SQL

6 svar · 2 300 visningar · startad av Vinnaren

Medlem sedan sep. 2005833 inlägg
Frågan#1

Tänkte göra en sql sats som hämtar ut alla bilder så länge summan av storleken är under 100.

Har följande:

	SELECT PhotoNr 
	INTO #PhotoTabl 
	FROM BlogPhoto 
	WHERE [I]Size <=100[/I]

	ORDER BY PhotoOrder ASC

Innehåll:
PhotoNr...Size
1............20
2............50
3............20
4............50
5............20

Ska ge resultatet:
PhotoNr...Size
1............20
2............50
3............20

Finns det någon bra lösning på detta? :stud
Databas: MSSQL

Medlem sedan juni 2000547 inlägg
#2
SELECT PhotoNr 
	INTO #PhotoTabl 
	FROM BlogPhoto 
	WHERE Size <=100

Det där borde väl funka utmärkt, förutsatt att tabellen ser ut som i ditt exempel ovan samt att det är korrekt storlek på bilderna angivet i databasen.

Dock så skulle ovanstående fråga ge samtliga resultat enligt ditt exempel eftersom det inte finns någon bild vars storlek inte är större än 100.

Medlem sedan mars 20034 471 inlägg
#3

SilvioF - Det där hämtar ut alla bilder som har egen storlek < 100, frågan gällde summa < 100.

Vinnaren - Du bör kunna göra på två olika sätt, men det är antagligen enklast att använda en CURSOR:

Syntax nedan med reservation för att jag inte använt MySQL på länge och lite snabbt försökt sätta mig in i MySQL:s syntax för CURSORS.

DECLARE 
   PhotoNrV, SizeV, SizeSum, RowAmount int

SET SizeSum = 0

CREATE TEMPORARY TABLE ShowPhotos (PhotoNr int, Size int)

DECLARE MyCur CURSOR FOR
SELECT PhotoNr, Size FROM BlogPhoto;
OPEN MyCur

select FOUND_ROWS() into RowAmount;

the_loop: LOOP

   FETCH MyCur INTO PhotoNrV, SizeV;

   -- End loop if we're through or have all we need
   IF SizeSum >= 100 OR RowAmount = 0 THEN
   BEGIN

        CLOSE MyCur;
        LEAVE the_loop;

   END;
   ELSE 
      SET RowAmount = RowAmount - 1;
   END IF;
 
   SET SizeSum = SizeSum + SizeV

   IF SizeSum < 100
   BEGIN

      INSERT INTO ShowPhotos (PhotoNr, Size)
      VALUES (PhotoNr, SizeV)

   END

END LOOP the_loop;

-- Hämta ut de bilder du vill visa
SELECT * FROM ShowPhotos

-- Städa
DROP TEMPORARY TABLE ShowPhotos
Medlem sedan juni 200032 967 inlägg
#4

Hmm.

Borde det inte gå att lösa med en liten HAVING?

SELECT PhotoNr, PhotoOrder, SUM(Size) AS summa 
	FROM BlogPhoto 
	HAVING SUM(Size) <=100
	GROUP BY PhotoNr, PhotoOrder
	ORDER BY PhotoOrder

mvh

Medlem sedan mars 20034 471 inlägg
#5

@nders skrev:

Hmm.

Borde det inte gå att lösa med en liten HAVING?

SELECT PhotoNr, PhotoOrder, SUM(Size) AS summa 
	FROM BlogPhoto 
	HAVING SUM(Size) <=100
	GROUP BY PhotoNr, PhotoOrder
	ORDER BY PhotoOrder

mvh

Nej, för i och med att du grupperar på PhotoNr så kommer du alltid att "summera" den bildens storlek, så resultatet av detta är samma som att bara jämjöra Size < 100 i en vanlig WHERE.

(Sedan, om inte MySQL:s syntax är annorlunda mot all annan SQL så kommer having efter GROUP BY och inte före.)

Däremot kan man laborera med en vanlig while, en parameter som avgör hur många rader vi ska plocka ut, köra successiva GROUP BY inne i slingan och ta sig fram den vägen, men jag tror inte det blir lättare än en CURSOR lösning. Alltså som pseudokod:

SET PhotoAmount int = 0, SumSize int = 0, TotalPhotos int

SELECT TotalPhotos = COUNT(PhotoNr) FROM BlogPhoto

WHILE SumSize < 100 AND PhotoAmount < TotalPhotos 
BEGIN

    SET PhotoAmount  = PhotoAmount + 1

    SELECT SumSize = SUM(Size) FROM BlogPhoto ORDER BY PhotoNr ASC LIMIT PhotoAmount  
     -- Eller hur det nu ser ut i MySQL De första PhotoAmount bilderna

END

IF SumSize >= 100
   SET PhotoAmount  = PhotoAmount - 1 -- Fick med en för mycket

SELECT * FROM BlogPhoto ORDER BY PhotoNr ASC LIMIT PhotoAmount

END

OBS! att detta inte är MySQL-kod!

Medlem sedan juni 200032 967 inlägg
#6

Jag måste ha missförstått frågan - men du har nog rätt. (Dessutom har du helt rätt i att having ska var efter group by. Jag skyller på att jag har semester. :) )

Dock - frågan gäller MSSQL, inte MySQL.

Medlem sedan sep. 2005833 inlägg
#7

Tack, men löste det med:

select
  PhotoNr
from BlogPhoto AS p
  cross apply (
    select tot = sum(Size) from BlogPhoto AS sub
    where sub.PhotoNr<= p.PhotoNr) x
where tot <= 100

Kanske inte den bästa lösningen gällande prestanda, men den funkar. §e

279 ms totalt · 4 externa anrop · v20260731065814-full.a51de22e
136 ms — deklarationer (db)
0 ms — hämta statistik (cache)
136 ms — hämta tråd, inlägg och bilagor (db)
140 ms — ändringar (db)