Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]13179[/thread]

Subselect - wie bekomme ich ein TRUE, wenn KEINE Einträge vorhanden sind?



<< >> 7 Einträge, 1 Seite
olruebe01
 2009-02-25 14:36
#119129 #119129
User since
2006-01-19
192 Artikel
BenutzerIn
[default_avatar]
Hallo Forum.

Ich stehe mal wieder auf dem Schlauch.

Ich habe 2 Tabellen (hier mal vereinfacht dargestellt): "ebay-Artikel" und "abgegebene Gebote".
In ebay-Artikel stehen alle Artikeldaten von allen möglichen Artikeln und in Gebote, stehen alle Angaben zu bisher abgegebenen Gebote, inklusive der Angabe, ob ein Gebot das Höchstgebot war oder nicht und aus welcher eBay-Kategorie der Artikel stammt.
Nun möchte ich einen(!) zufälligen Artikel aus einer eBay-Kategorie, in der ich bisher auf weniger als 3 Artikel der Höchstbietende bin. Also im Klartext: Ich möchte solange Autoradios angezeigt bekommen, bis in der Tabelle gebote 3 Gebote verzeichnet sind, auf die ich der Höchstbietende bin


Hierfür joine ich zuerst die Tabellen:
Code: (dl )
Select  ebay_id from Artikel LEFT JOIN gebote ON (Artikel.ID = gebote.artikel_id)


Soweit so gut. Jetzt kommt die Bedingung in einem Subselect...
Code: (dl )
1
2
3
4
5
6
7
WHERE (SELECT count( * ) 
FROM gebote
WHERE user_id =1
AND high_bid =1
GROUP BY category, user_id
) <3
Limit 1 Order by Rand()


Soweit so gut. Das ganze klappt tatsächlich, solange ich weniger als 3 Artikel beboten habe. Habe ich jedoch in der TAbelle gebote KEINEN Eintrag, weil ich bisher noch kein Gebot auf ein Autradio abgegeben habe, findet der Subselect nichts und bedingung <3 ist nicht erfüllt :-(

Ich dokter jetzt seit 2 Tagen daran. Ich habe es auch mit having probiert. Damit bekomme ich die gleiche Lösung hin. Aber auch hier ist es so, solange 1 oder 2 Artikel in der Tabelle stehen, funzt es. Steht jedich gar keiner drinnen, gehts nicht mehr weiter.

Not Exists hat mich auch nicht nach vorn gebracht. Hat hier jemand den enstscheidenden Tipp, wo ich den Fehler mache, bzw. wie der richtige Google-Suchbegriff heißt?

Danke schon Mal.
Spieler
 2009-02-25 16:02
#119134 #119134
User since
2007-09-24
70 Artikel
BenutzerIn
[default_avatar]
In postgres gibt es coalesce(), und ich glaube, das ist SQL Standard:
Code: (dl )
1
2
SELECT coalesce ((SELECT 1 WHERE 'f'),0);
0
olruebe01
 2009-02-25 16:39
#119136 #119136
User since
2006-01-19
192 Artikel
BenutzerIn
[default_avatar]
erstmal Danke.

wenn ich diesen TEst mache...
Code: (dl )
select coalesce (NULL, NULL, 'hallo welt')


bekomme ich die Fehlermeldung
#1305 - FUNCTION test.coalesce does not exist

:-(
murphy
 2009-02-25 17:53
#119139 #119139
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
olruebe01+2009-02-25 13:36:33--
[...]
Soweit so gut. Das ganze klappt tatsächlich, solange ich weniger als 3 Artikel beboten habe. Habe ich jedoch in der TAbelle gebote KEINEN Eintrag, weil ich bisher noch kein Gebot auf ein Autradio abgegeben habe, findet der Subselect nichts und bedingung <3 ist nicht erfüllt :-(
[...]


Bist Du ganz sicher, dass das Problem an dieser Stelle sitzt? Ich kenne keine Datenbank, bei der ein SELECT count(*) auf eine leere Tabelle etwas anderes als 0 zurueckliefert (ich habe auch gerade nochmal mit SQLite3 und PostgreSQL, die ich zur Hand hatte, getestet). In dem Falle muesste Dein Ausdruck aber funktionieren...

Quote
[...]
Not Exists hat mich auch nicht nach vorn gebracht.
[...]


Neben coalesce gibt's bei manchen Datenbanken auch eine aehnliche Funktion namens ifnull. Ich kann mir jedenfalls nicht vorstellen, dass sich nichts in dieser Richtung im Handbuch der Datenbank finden lassen sollte...

Im Notfall kannst Du auch noch ein SELECT NOT EXISTS und Deine bisherige Abfrage mit OR kombinieren, was zwar haesslich ist, aber auf jeden Fall funktionieren sollte.
When C++ is your hammer, every problem looks like your thumb.
olruebe01
 2009-02-25 19:02
#119145 #119145
User since
2006-01-19
192 Artikel
BenutzerIn
[default_avatar]
Hi murphy,

0 war es defintiv nicht. Vielleicht leigt es daran, dass es ein Subselect ist? Ich weiß es nicht...

Nach vielen Google habe ich IFNULL auch gefunden und damit klappt es soweit. Juhu. Jetzt habe ich nur eine neues Problem, dass ich bisher noch nciht lösen konnte: Mit hilfe dieses Subselects möchte ich erreichen, dass dass ich keinen Artikel aus einer Kategorie ausgegeben bekomme, in der das Limit an Höchstgeboten bereits erreicht ist. Stattdessen möchte ich dann einen Artikel aus einer anderen Kategorie. Klappt aber leidre nicht nicht ganz. Sobald eine Kategorie "voll" ist, bekomme ich auch keine andere mehr ausgegeben...

Aber das bekomme ich auch noch hin. Erstmal Danke für IFNULL, das war der entscheidende Hinweis.
olruebe01
 2009-02-25 21:28
#119153 #119153
User since
2006-01-19
192 Artikel
BenutzerIn
[default_avatar]
Kennt Ihr das, wenn Ihr nach Tagen den Wald vor lauter Bäumen nicht mehr seht und auch nicht mehr wisst, was Ihr nun schon alles ausprobiert habt und wie dabei das Ergebnis war?
Bei mir ist es gerade mal wieder soweit und ich gebe für den Moment auf, denn sonst lande ich noch in der Klappse...

Könnt Ihr mir helfen?
Das Ziel: Ich habe in meiner Tabelle user_settings angegeben, auf wieviele Artikel einer gleichen Kategorie ich maximal gleichzeitg höchstbietender sein will. Es gibt mehere Angaben für unterschiedliche Kategorien, z.B. 5 Autradios, 3 Modellflugzeuge, etc. und auch für unterschiedliche User

Nun soll aus der Tabelle items ein Artikel aus einer Kategorie ausgegeben werden, auf den ich noch nicht geboten habe und wo die Anzahl an höchstgeboten auf andere Artikel aus der gleichen Katerorie kleiner ist als in meinen user_settings angegeben. Ein paar andere Bedingungen gibt es auch noch aber die machen keine Probleme und erklären sich aus dem Statement selber denke ich.
Hier mein Statement

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
		SELECT 
items.title,
items.subtitle,
items.ebay_id AS item_id,
items.actual_price AS actual_price,
items.max_bid,
items.image_url,
user_settings.category,
user_settings.minbid,
user_settings.maxbid,
user_settings.item_condition,
user_settings.max_items_to_buy
FROM `users`
LEFT JOIN user_settings ON ( users.ID = user_settings.user_id)
LEFT JOIN items ON ( items.primary_category = user_settings.category)
LEFT JOIN placed_bids ON (placed_bids.user_id = users.ID)


WHERE
users.ebay_name ='".$GET_ARRAY["user_id"]."'

AND
(
user_settings.minbid >= items.actual_price
OR user_settings.minbid < 1
)

AND
(
user_settings.maxbid <= items.actual_price
OR user_settings.maxbid <1
)
AND
user_settings.category = items.primary_category


AND
items.item_closed=0

AND
items.actual_price < items.max_bid

AND
item_ends + INTERVAL 1 HOUR > NOW( )


Group by placed_bids.category,placed_bids.user_id

having (SELECT count(*) from placed_bids WHERE
user_id = users.ID AND high_bid =1
and category = items.primary_category group by category) < user_settings.max_items_to_buy


ORDER BY RAND()
LIMIT 1


Das ist eine von gefühlt hunderten Variationen, die ich probiert habe.

Ich lande immer wieder bei den selben Problemen:
1: dass keine Kategorien berücksichtigt werden, wenn noch GAR KEINE Gebote in einer Kategorie vorliegen (also in der Tabelle placed_bids) - Dieses Problem konnte ich mit IFNULL beheben. Dann trat aber wieder Problem 2 auf.
2: Dass gar kein Ausgegeben wird, wenn eine(!) Kategorie Ihre maximal Höchstzahl an Geboten hat.

Bei der oben gezeigten Abfrage ist das Problem folgendes:
Ich gebe in user_settings an, dass ich in Kategorie A auf 5 Artikel möchten möchte und in Kategorie B auf 2.
Das klappt erstmal. Ich bekomme solange beide Kategorien ausgegeben, bis B 2 Höchstgebote hat. Ab dahin nur noch aus Kat A. SO soll es sein.
Aber andere Situation: Ich habe meien Anzahl in Kat B noch ncit erreicht, in A aber schon, dann bekomme ich GAR KEINE Ausgabe mehr. Auch nicht Kat B, was aber das Ziel wäre.
Offensichtlich ist es so, dass bei erreichen des größeren eingestellten Wertes gleich ALLES geblockt wird. Wird jedoch zuerst die kleinere Anzahl höchstgebote erreicht, wird ganz korrekt nur die betroffene Kategorie für die Ausgabe geblockt.

Kann mir jemand mal bitte tatkräftig unter die Arme greifen?
olruebe01
 2009-02-25 21:49
#119154 #119154
User since
2006-01-19
192 Artikel
BenutzerIn
[default_avatar]
Kennt Ihr das, wenn Ihr nach Tagen den Wald vor lauter Bäumen nicht mehr seht und auch nicht mehr wisst, was Ihr nun schon alles ausprobiert habt und wie dabei das Ergebnis war?
Bei mir ist es gerade mal wieder soweit und ich gebe für den Moment auf, denn sonst lande ich noch in der Klappse...

Könnt Ihr mir helfen?
Das Ziel: Ich habe in meiner Tabelle user_settings angegeben, auf wieviele Artikel einer gleichen Kategorie ich maximal gleichzeitg höchstbietender sein will. Es gibt mehere Angaben für unterschiedliche Kategorien, z.B. 5 Autradios, 3 Modellflugzeuge, etc. und auch für unterschiedliche User

Nun soll aus der Tabelle items ein Artikel aus einer Kategorie ausgegeben werden, auf den ich noch nicht geboten habe und wo die Anzahl an höchstgeboten auf andere Artikel aus der gleichen Katerorie kleiner ist als in meinen user_settings angegeben. Ein paar andere Bedingungen gibt es auch noch aber die machen keine Probleme und erklären sich aus dem Statement selber denke ich.
Hier mein Statement

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
		
SELECT
items.title,
items.subtitle,
items.ebay_id AS item_id,
items.actual_price AS actual_price,
items.max_bid,
items.image_url,
user_settings.category,
user_settings.minbid,
user_settings.maxbid,
user_settings.item_condition,
user_settings.max_items_to_buy
FROM `users`
LEFT JOIN user_settings ON ( users.ID = user_settings.user_id)
LEFT JOIN items ON ( items.primary_category = user_settings.category)
LEFT JOIN placed_bids ON (placed_bids.user_id = users.ID AND user_settings.category = placed_bids.category AND placed_bids.ebay_id = items.ebay_id)


WHERE
users.ebay_name ='".$GET_ARRAY["user_id"]."'

AND
(
user_settings.minbid >= items.actual_price
OR user_settings.minbid < 1
)

AND
(
user_settings.maxbid <= items.actual_price
OR user_settings.maxbid <1
)
AND
user_settings.category = items.primary_category


AND
items.item_closed=0

AND
items.actual_price < items.max_bid

AND
item_ends + INTERVAL 1 HOUR > NOW( )


having (SELECT count(*) from placed_bids WHERE
user_id = users.ID AND high_bid =1
and category = items.primary_category group by category) < user_settings.max_items_to_buy


ORDER BY RAND()
LIMIT 1


Das ist eine von gefühlt hunderten Variationen, die ich probiert habe.

Ich lande immer wieder bei den selben Problemen:
1: dass keine Kategorien berücksichtigt werden, wenn noch GAR KEINE Gebote in einer Kategorie vorliegen (also in der Tabelle placed_bids) - Dieses Problem konnte ich mit IFNULL beheben. Dann trat aber wieder Problem 2 auf.
2: Dass gar kein Ausgegeben wird, wenn eine(!) Kategorie Ihre maximal Höchstzahl an Geboten hat.

Bei der oben gezeigten Abfrage ist das Problem folgendes:
Ich gebe in user_settings an, dass ich in Kategorie A auf 5 Artikel möchten möchte und in Kategorie B auf 2.
Das klappt erstmal. Ich bekomme solange beide Kategorien ausgegeben, bis B 2 Höchstgebote hat. Ab dahin nur noch aus Kat A. SO soll es sein.
Aber andere Situation: Ich habe meien Anzahl in Kat B noch ncit erreicht, in A aber schon, dann bekomme ich GAR KEINE Ausgabe mehr. Auch nicht Kat B, was aber das Ziel wäre.
Offensichtlich ist es so, dass bei erreichen des größeren eingestellten Wertes gleich ALLES geblockt wird. Wird jedoch zuerst die kleinere Anzahl höchstgebote erreicht, wird ganz korrekt nur die betroffene Kategorie für die Ausgabe geblockt.

Kann mir jemand mal bitte tatkräftig unter die Arme greifen?
<< >> 7 Einträge, 1 Seite



View all threads created 2009-02-25 14:36.