SQL: Aktuelle Gebotshöhe bei Auktionen

SQL: Aktuelle Gebotshöhe bei Auktionen

am 11.12.2006 22:20:18 von Guido Schmidt

Tabelle Auktionen:
auktions_id | startpreis
1 | 12
2 | 15
3 | 16

Tabelle Gebote:
auktions_id | gebot
2 | 21
3 | 18
3 | 23
3 | 31

Ich möchte jetzt in einem SQL-Statement den aktuellen Preis für alle =

Auktionen ermitteln:

auktions_id | aktueller_preis
1 | 12
2 | 15
3 | 24

Auktion 1: kein Gebot =3D> Startpreis
Auktion 2: ein Gebot =3D> Startpreis
Auktion 3: 3 Gebote =3D> zweithöchstes Gebot + 1

Gibt es Vorschläge für eine elegante Lösung (MySQL 5)?

Danke

Guido

Re: SQL: Aktuelle Gebotshöhebei Auktionen

am 11.12.2006 22:50:09 von Harald Fuchs

In article ,
Guido Schmidt writes:

> Tabelle Auktionen:
> auktions_id | startpreis
> 1 | 12
> 2 | 15
> 3 | 16

> Tabelle Gebote:
> auktions_id | gebot
> 2 | 21
> 3 | 18
> 3 | 23
> 3 | 31

> Ich möchte jetzt in einem SQL-Statement den aktuellen Preis für alle
> Auktionen ermitteln:

> auktions_id | aktueller_preis
> 1 | 12
> 2 | 15
> 3 | 24

> Auktion 1: kein Gebot =3D> Startpreis
> Auktion 2: ein Gebot =3D> Startpreis
> Auktion 3: 3 Gebote =3D> zweithöchstes Gebot + 1

Wirklich zweithöchstes Gebot + 1? Da fällt mir nichts Elegantes dazu e=
in:

SELECT a.auktions_id, coalesce(g.gebot + 1, a.startpreis) AS aktueller_prei=
s
FROM auktionen a
LEFT JOIN gebote g ON g.auktions_id =3D a.auktions_id
AND (SELECT count(*)
FROM gebote g1
WHERE g1.auktions_id =3D g.auktions_id
AND g1.gebot > g.gebot
) =3D 1

Re: SQL: Aktuelle Gebotshöhe bei Auktionen

am 11.12.2006 23:13:03 von Heiko Richler

Hallo Guido,

> Ich möchte jetzt in einem SQL-Statement den aktuellen Preis für alle
> Auktionen ermitteln:

grob und spontan:

Eine View "Verlauf" anlegen:

select auktions_id, startpreis as preis, startpreis as folgepreis
from Auktionen
union
select auktions_id, gebot as preis, gebot + 1 as folgepreis
from Gebote


select auktions_id, (
select auktions_id, folgepreis
from Verlauf as v1
where v1.auktions_id=Auktionen.auktions_id
preis <=
(select max(preis)
from Verlauf as v2
where v2.auktions_id=v1.auktions_id)
order by folgepreis desc limit 1) as aktueller_preis
from Auktionen


Da lässt sich noch einiges optimieren!


Brauchst Du eher Geschwindigkeit oder ein robustes Datenmodell?

Um das zu beschleunigen könntest Du bei Verlauf als Tabelle anlegen oder
bei jedem Gebot die letzten Gebote speichern. Das könnte ein Trigger
auch automatisch erledigen.


Ich nehme an Du hast mehr Abfrage- als Speicherzugriffe? Darum könntest
Du Dein Modell umstellen und damit Abfragezugriffe erleichtern:

Auktionen:
auktions_id, [cur_pos,] ... (Beschreibungen)

Gebote:
auktions_id, pos, Betrag

pos=0 ist der Startpreis


Gruß

Heiko
--
http://portal.richler.de/ Namensportal zu Richler
http://www.richler.de/ Heiko Richler: Computer - Know How!
http://www.richler.info/ private Homepage

Re: SQL: Aktuelle Gebotshöhebei Auktionen

am 12.12.2006 06:29:54 von Guido Schmidt

Harald Fuchs schrieb:

Vielen Dank für die Antwort!

> Wirklich zweithöchstes Gebot + 1? =20

Ja, Wie bei eBay, anderen Online-Auktionshäusern und Präsenz-Auktione=
n=20
mit Vorgeboten auch. Wenn das aktuelle Gebot bei 23 EUR steht und ich=20
dann 31 EUR als Gebot eingebe, so steigt der Preis nur so weit wie=20
nötig, um eben das Höchstgebot zu haben. Das heißt zweithöchstes =
Gebot +=20
Preissteigerungsstufe.

Das Ganze ist für eine ganz spezielle kleine Plattform, bei der Traffic=
,=20
Performance auf absehbare Zeit nach derzeitigem Stand eine=20
untergeordnete Rolle spielen.

Guido

Re: SQL: Aktuelle Gebotshöhe bei Auktionen

am 12.12.2006 06:39:24 von Guido Schmidt

Heiko Richler schrieb:

Vielen Dank für die Antwort!

> Brauchst Du eher Geschwindigkeit oder ein robustes Datenmodell?

Derzeit eher Letzteres. Das ist nur eine Plattform für einen sehr=20
kleinen Kundenkreis. Da werden kaum mal mehr als 100 Auktionen=20
gleichzeitig laufen.

In der Realität ist das Ganze noch etwas kniffliger, da in der Abfrage =

ohnehin schon 8 Tabellen verknüpft werden. Weiterhin ist die=20
Preisermittlung real noch komplexer, weil es auch noch reverse Auktionen =

gibt (Preis sinkt jeweils um den Betrag n im Zeitintervall s). Von daher =

überlege ich fast, ob ich bewusst ein bisschen auf Normalisierung=20
verzichte und in der Tabelle auktionen ein zusätzliches Feld für den =

aktuellen Preis führe, welches bei jeder Gebotsabgabe aktualisiert wird=


Guido

Re: SQL: Aktuelle Gebotshöhe bei Auktionen

am 12.12.2006 12:31:36 von dnoeth

Guido Schmidt wrote:

> Tabelle Auktionen:
> auktions_id | startpreis
> 1 | 12
> 2 | 15
> 3 | 16
>
> Tabelle Gebote:
> auktions_id | gebot
> 2 | 21
> 3 | 18
> 3 | 23
> 3 | 31
>
> Ich möchte jetzt in einem SQL-Statement den aktuellen Preis für alle
> Auktionen ermitteln:
>
> auktions_id | aktueller_preis
> 1 | 12
> 2 | 15
> 3 | 24
>
> Auktion 1: kein Gebot => Startpreis
> Auktion 2: ein Gebot => Startpreis
> Auktion 3: 3 Gebote => zweithöchstes Gebot + 1

Da MySQL Subqueries schlecht optimiert, das Ganze mit Derived Tables:

SELECT
a.auktions_id,
COALESCE(MaxGebot + 1, StartPreis)
FROM auktionen AS a LEFT JOIN
(
SELECT
g.auktions_id,
MAX(Gebot) AS MaxGebot -- Zweithöchstes Gebot
FROM gebote AS g JOIN
(
SELECT
auktions_id,
MAX(gebot) AS MaxGebot -- Höchstgebot...
FROM gebote
GROUP BY auktions_id
HAVING COUNT(*) > 1 -- ...falls mehr als ein Gebot existiert
) AS dt
ON g.auktions_id = dt.auktions_id
AND g.Gebot < dt.MaxGebot -- nur Gebote unterhalb des Höchstgebotes
GROUP BY g.auktions_id
) AS g
ON a.auktions_id = g.auktions_id

Dieter