mysql: Trick gesucht
Fletch
- datenbank
Hallo,
mir fällt leider keine bessere Überschrift für meinen Beitrag ein. Ich versuche mal zu beschreiben, worum es geht.
Ich habe eine (für mich) komplizierte Abfrage erstellt, in die ich noch ein zusätzliches Feature einbauen muss.
SELECT
sum(
Menge*Preis*
(CASE
WHEN Multi = '100' THEN 1
WHEN Multi = '125' THEN 1.25
END)
*
(1-Nachlass/100) ) AS count
FROM Artikel_Tabelle...
Diese Abfrage berechnet aus einer Tabelle den Gesamtwert abzüglich der Artikelabzüge.
Es gibt aber in einer 2. Tabelle ggf. auch noch Gesamtabzüge auf den Warenkorb. Also z.b. 10% Rabatt auf den Artikel und zudem 3% auf den Gesamtwarenkorb.
An die Warenkorb-ID komme ich über die Artikel_Tabelle, dort steht sie drin.
Aber ich weiß nicht, an welcher Stelle und vor allem wie ich das in die Abfrage einbauen kann.
Kann mir mal jemand diesbzgl. unter die Arme greifen?
Grüße, Fletch
(CASE
WHEN Multi = '100' THEN 1
WHEN Multi = '125' THEN 1.25
END)
Wie wäre es wenn du anstatt dem case einfach durch 100 teilst? Wie man ein Komma verschieben kann, sollte man eigentlich nach erfolgreicherm Absolvieren der Grundschule oder Volksschule durchaus draufhaben.
Diese Abfrage berechnet aus einer Tabelle den Gesamtwert abzüglich der Artikelabzüge.
Es gibt aber in einer 2. Tabelle ggf. auch noch Gesamtabzüge auf den Warenkorb. Also z.b. 10% Rabatt auf den Artikel und zudem 3% auf den Gesamtwarenkorb.
An die Warenkorb-ID komme ich über die Artikel_Tabelle, dort steht sie drin.
Aber ich weiß nicht, an welcher Stelle und vor allem wie ich das in die Abfrage einbauen kann.
http://aktuell.de.selfhtml.org/artikel/datenbanken/joins/
Vermutlich wird dir ein LEFT JOIN behilflich sein, die linke Tabelle ist dabei der Warenkorb (in der die Artikel-Nummer steht), die Rechte Tabelle die Artikel-Tabelle (in der die Rabatte stehen) - verknöpft werden die beiden Tabellen (ON) über die die Artikelnummer.
Wie wäre es wenn du anstatt dem case einfach durch 100 teilst? Wie man ein Komma verschieben kann, sollte man eigentlich nach erfolgreicherm Absolvieren der Grundschule oder Volksschule durchaus draufhaben.
Warum denn gleich einen Seitehieb auf mich? Habe ich was falsch gemacht bei meiner Frage?
Das "case" geht in Ordnung, ich habe der Übersichtlichkeit halber die restlichen Fälle aus der Abfrage herausgelassen. Durch 100 teilen hätte da nicht gegriffen.
Vermutlich wird dir ein LEFT JOIN behilflich sein, die linke Tabelle ist dabei der Warenkorb (in der die Artikel-Nummer steht), die Rechte Tabelle die Artikel-Tabelle (in der die Rabatte stehen) - verknöpft werden die beiden Tabellen (ON) über die die Artikelnummer.
Ich habe mich sicher falsch ausgedrückt. Aber die Sache ist so:
Tabelle Artikel:
ID|Warenkorb_ID|Menge|Preis|Nachlass|Multi|...
Tabelle Warenkorb:
ID|User_ID|Datum|Warenkorb_Nachlass|...
Grüße, Fletch
Warum denn gleich einen Seitehieb auf mich? Habe ich was falsch gemacht bei meiner Frage?
Deine Augenscheinlich komplizierte Abfrage (zumindest den teil den du davon präsentierst) ist vorrangig deshalb kompliziert, weil er kompliziert geschrieben ist und es extrem viel einfacher geht ...
Das "case" geht in Ordnung, ich habe der Übersichtlichkeit halber die restlichen Fälle aus der Abfrage herausgelassen. Durch 100 teilen hätte da nicht gegriffen.
... sofern man eben diese Information nicht hat.
Dann hättest du dir den Schnipsel gleich sparen können und SELECT 1 as sum reinschreiben können.
Ich habe mich sicher falsch ausgedrückt. Aber die Sache ist so:
Tabelle Artikel:
ID|Warenkorb_ID|Menge|Preis|Nachlass|Multi|...Tabelle Warenkorb:
ID|User_ID|Datum|Warenkorb_Nachlass|...
Irgend eine Zuordnung zwischen Artikel und Warenkorb muss es geben - und über dieses Feld verbindest du beide Tabellen - und ich gehe stark davon aus, dass es in Tabelle_Warenkorb ein Feld mit Artikel_ID oder ähnliches geben wird.
Irgend eine Zuordnung zwischen Artikel und Warenkorb muss es geben - und über dieses Feld verbindest du beide Tabellen - und ich gehe stark davon aus, dass es in Tabelle_Warenkorb ein Feld mit Artikel_ID oder ähnliches geben wird.
Ja, die gibt es:
und ich gehe stark davon aus, dass es in Tabelle_Warenkorb ein Feld mit Artikel_ID oder ähnliches geben wird.
Nein. Ich wünschte, ich könnte es farblich markieren:
Tabelle Artikel:
ID|Warenkorb_ID|Menge|Preis|Nachlass|Multi|...Tabelle Warenkorb:
ID|User_ID|Datum|Warenkorb_Nachlass|...
LEFT JOINS kenne ich auch. Aber ich weiß trotzdem nicht, wie ich innerhalb einer "sum()" kenntlich mache, dass nur einzelne Artikel von diesem JOIN betroffen sind.
Gruß, Fletch
Tabelle Artikel:
ID|Warenkorb_ID|Menge|Preis|Nachlass|Multi|...Tabelle Warenkorb:
ID|User_ID|Datum|Warenkorb_Nachlass|...
Irgendwie kommt mir das jetzt nicht sehr schlau vor, dass ein Artikel mehrere Warenkörbe besitzen kann - normalerweise sollte das umgekehrt sein.
LEFT JOINS kenne ich auch. Aber ich weiß trotzdem nicht, wie ich innerhalb einer "sum()" kenntlich mache, dass nur einzelne Artikel von diesem JOIN betroffen sind.
SELECT
(t_artikel.preis * t_artikel.rabatt) as artikelpreis,
sum(artikelpreis) as summe_aller_artikel,
(summe_aller_artikel * t_warenkorb.rabatt) as endpreis
FROM
Tabelle_Warenkorb as t_warenkorb
JOIN -- usw.
Irgendwie kommt mir das jetzt nicht sehr schlau vor, dass ein Artikel mehrere Warenkörbe besitzen kann - normalerweise sollte das umgekehrt sein.
Ok, da hast Du sicher recht.
SELECT
(t_artikel.preis * t_artikel.rabatt) as artikelpreis,
sum(artikelpreis) as summe_aller_artikel,
(summe_aller_artikel * t_warenkorb.rabatt) as endpreis
FROM
Tabelle_Warenkorb as t_warenkorb
JOIN -- usw.
Kann man das nur so lösen oder kann man das Gesamtrabattfeature auch in meine ursprüngliche Abfrage integrieren?
~~~sql
SELECT
sum(
Menge*Preis*
(CASE
WHEN Multi = '100' THEN 1
WHEN Multi = '125' THEN 1.25
END)
*
(1-Nachlass/100) ) AS count
FROM Artikel_Tabelle...
Gruß und danke fürs Helfen,
Fletch
Das kannst du sicher irgendwie da reinwursteln, aber ich würde das aus gründen der Lesbarkeit ganz einfach auf mehrere Berechungsschritte aufteilen die man dann auch getrennt verwenden kann - das ist bei Darstellungen üblicherweise auch gewünscht.
Summe xx
Rabatt -yy
Endsumme zz
Und wenn du die Zahlen nicht brauchst, zeigst du sie halt nicht an.
Hi,
Irgendwie kommt mir das jetzt nicht sehr schlau vor, dass ein Artikel mehrere Warenkörbe besitzen kann - normalerweise sollte das umgekehrt sein.
Ok, da hast Du sicher recht.
Gut - und was gedenkst du dagegen zu unternehmen?
Kann man das nur so lösen oder kann man das Gesamtrabattfeature auch in meine ursprüngliche Abfrage integrieren?
SELECT
sum(
MengePreis
(CASE
WHEN Multi = '100' THEN 1
WHEN Multi = '125' THEN 1.25
END)
*
(1-Nachlass/100) ) AS count
FROM Artikel_Tabelle...
Kommt für das, was hier berechnet wird, nur ein Warenkorb-Rabatt zum tragen, oder mehrere?
Wenn es nur einer ist, und du ihn hinzu joinst, dann brauchst du doch nur noch die einzelnen Posten, die du da aufsummierst, mit dem jeweiligen Faktor zu multiplizieren.
MfG ChrisB
--
RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
Gut - und was gedenkst du dagegen zu unternehmen?
Das ist bereits scriptmäßig unterbunden.
Kann man das nur so lösen oder kann man das Gesamtrabattfeature auch in meine ursprüngliche Abfrage integrieren?
SELECT
sum(
MengePreis
(CASE
WHEN Multi = '100' THEN 1
WHEN Multi = '125' THEN 1.25
END)
*
(1-Nachlass/100) ) AS count
FROM Artikel_Tabelle...
>
> Kommt für das, was hier berechnet wird, nur ein Warenkorb-Rabatt zum tragen, oder mehrere?
>
Es ist nur einer.
> Wenn es nur einer ist, und du ihn hinzu joinst, dann brauchst du doch nur noch die einzelnen Posten, die du da aufsummierst, mit dem jeweiligen Faktor zu multiplizieren.
>
Ach, so einfach geht das?
Also so??:
~~~sql
SELECT
sum(
artikel.Menge*artikel.Preis*
(CASE
WHEN artikel.Multi = '100' THEN 1
WHEN artikel.Multi = '125' THEN 1.25
END)
*
(1-artikel.Nachlass/100)
*
(1-warenkorb.Rabatt/100) ) AS count
FROM artikel
JOIN warenkorb
ON artikel.warenkorb_id = warenkorb.id
Korrekt?
Grüße, Fletch
Hi,
Wenn es nur einer ist, und du ihn hinzu joinst, dann brauchst du doch nur noch die einzelnen Posten, die du da aufsummierst, mit dem jeweiligen Faktor zu multiplizieren.
Ach, so einfach geht das?
Kommt damit das raus, was du haben möchtest? (Ich bin mir immer noch nicht sicher, was dein eigentliches Problem angeht.)
Falls ja, dann wären wir irgendwie wieder beim Thema Grundschulwissen - das ist dann nämlich eigentlich nur die Anwendung des Distributivgesetzes ...
MfG ChrisB
Falls ja, dann wären wir irgendwie wieder beim Thema Grundschulwissen - das ist dann nämlich eigentlich nur die Anwendung des Distributivgesetzes ...
Es kommt das raus, was ich haben möchte.
Obige Aussage ist doppelt falsch:
1. Lernt man das Distributivgesetz nicht in der Grundschule.
2. Inwiefern kommst Du darauf, dass das inflechten eines JOINS dem entspricht?
Gruß, Fletch
Hi,
Falls ja, dann wären wir irgendwie wieder beim Thema Grundschulwissen - das ist dann nämlich eigentlich nur die Anwendung des Distributivgesetzes ...
Obige Aussage ist doppelt falsch:
- Lernt man das Distributivgesetz nicht in der Grundschule.
Da wäre ich mir nicht so sicher.
Ich weiß es zwar aus meiner Schulzeit nicht mehr definitiv, aber später als fünfte oder sechste Klasse kann's eigentlich kaum gewesen sein.
- Inwiefern kommst Du darauf, dass das inflechten eines JOINS dem entspricht?
Dir ging es darum, auf deinen „Gesamtwarenkorb“ einen Rabatt zu geben.
Mit deiner gezeigten Abfrage hast du zunächst aus den Werten der einzelnen Datensätze die Summe gebildet, und wolltest irgendwie „anschließend“ noch den Gesamtrabatt berechnen.
Dass man das nicht anschließend machen muss, sondern für den Wert jedes einzelnen Datensatzes „zwischendrin“ schon machen kann - das *ist* die Anwendung des Distributivgesetzes.
MfG ChrisB
aber später als fünfte oder sechste Klasse kann's eigentlich kaum gewesen sein.
Würde ich Dir beipflichten. 5. oder 6. haut hin.
Dir ging es darum, auf deinen „Gesamtwarenkorb“ einen Rabatt zu geben.
Mit deiner gezeigten Abfrage hast du zunächst aus den Werten der einzelnen Datensätze die Summe gebildet, und wolltest irgendwie „anschließend“ noch den Gesamtrabatt berechnen.
Dass man das nicht anschließend machen muss, sondern für den Wert jedes einzelnen Datensatzes „zwischendrin“ schon machen kann - das *ist* die Anwendung des Distributivgesetzes.
Mir gings nicht um "anschließend". Aber es stimmt, dass man das so auffassen konnte. Insofern ok, Distributivgesetz :-)
Danke für den entscheidenden Tip zur Lösung meines Problems auf jeden Fall.
Gruß, Fletch
Hi,
Tabelle Artikel:
ID|Warenkorb_ID|Menge|Preis|Nachlass|Multi|...
Irgendwie kommt mir das jetzt nicht sehr schlau vor, dass ein Artikel mehrere Warenkörbe besitzen kann
Gehst Du davon aus, daß in der Spalte Warenkorb_ID mehrere Werte drin stehen?
cu,
Andreas
Tabelle Artikel:
ID|Warenkorb_ID|Menge|Preis|Nachlass|Multi|...Irgendwie kommt mir das jetzt nicht sehr schlau vor, dass ein Artikel mehrere Warenkörbe besitzen kann
Gehst Du davon aus, daß in der Spalte Warenkorb_ID mehrere Werte drin stehen?
Entweder das oder in der Artikel-Tabelle gibt es für jeden Artikel mehrere Datensätze mit unterschiedlichen Warenkorb-IDs
Oder wie sonst sollte man einen Artikel in mehrere Warenkörbe legen könne? Ein Artikel wird ja wohl nicht nur von einem Benutzer bestellt werden können - sofern man nicht grade Unikate verkauft.
Oder wie sonst sollte man einen Artikel in mehrere Warenkörbe legen könne? Ein Artikel wird ja wohl nicht nur von einem Benutzer bestellt werden können - sofern man nicht grade Unikate verkauft.
Nein, die Tabelle Artikel führt Teile der verkauften Artikel redundant. Daher wird es in der Praxis nicht zu dem Problem kommen, das Du beschreibst.
Würde diese Tabelle Teile der Artikel nicht redundant führen, dürfte man niemals in der orgiginalen Artikel-Tabelle Änderungen machen, da man damit auch immer die verkauften Artikel mitverändern würde.
Grüße, Fletch
Nein, die Tabelle Artikel führt Teile der verkauften Artikel redundant. Daher wird es in der Praxis nicht zu dem Problem kommen, das Du beschreibst.
Würde diese Tabelle Teile der Artikel nicht redundant führen, dürfte man niemals in der orgiginalen Artikel-Tabelle Änderungen machen, da man damit auch immer die verkauften Artikel mitverändern würde.
Das ist üblicherweise kein Problem wenn man mit dem Artikel die daraus resultierende Rechnung abspeichert die man sowieso braucht - ob sich nachher ein Preis oder ein Rabatt ändert ist ansich egal - es sei denn, man braucht eine Versionierung der Datenstände, das ist aber etwas anderes.
Das ist üblicherweise kein Problem wenn man mit dem Artikel die daraus resultierende Rechnung abspeichert die man sowieso braucht - ob sich nachher ein Preis oder ein Rabatt ändert ist ansich egal - es sei denn, man braucht eine Versionierung der Datenstände, das ist aber etwas anderes.
Das, was ich hier lapidar mit Warenkorb bezeichnet habe, ist die Zusammenfassung der Rechnung ;-)
Grüße, Fletch
Das, was ich hier lapidar mit Warenkorb bezeichnet habe, ist die Zusammenfassung der Rechnung ;-)
Das ist natürlich ganz klar aus dem Treadverlauf zu erschnüffeln gewesen.
Das ist natürlich ganz klar aus dem Treadverlauf zu erschnüffeln gewesen.
Natürlich nicht.
Danke auf jeden Fall für die Hilfe.
Hi,
Tabelle Artikel:
ID|Warenkorb_ID|Menge|Preis|Nachlass|Multi|...
Irgendwie kommt mir das jetzt nicht sehr schlau vor, dass ein Artikel mehrere Warenkörbe besitzen kann
Gehst Du davon aus, daß in der Spalte Warenkorb_ID mehrere Werte drin stehen?Entweder das oder in der Artikel-Tabelle gibt es für jeden Artikel mehrere Datensätze mit unterschiedlichen Warenkorb-IDs
Ich gehe davon aus, daß es sich um bestellte Artikel handelt.
Nicht um Sortiments-Artikel.
cu,
Andreas
Mahlzeit Fletch,
Warum denn gleich einen Seitehieb auf mich? Habe ich was falsch gemacht bei meiner Frage?
Bei der Frage nicht - eher beim Tabellendesign.
Das "case" geht in Ordnung, ich habe der Übersichtlichkeit halber die restlichen Fälle aus der Abfrage herausgelassen. Durch 100 teilen hätte da nicht gegriffen.
Das CASE geht eben *nicht* in Ordnung:
CASE
WHEN Multi = '100' THEN 1
WHEN Multi = '125' THEN 1.25
END
Du schriebst, dass in der Spalte "Multi" noch weitere Werte enthalten sein können. Da Du diese nicht in Deinem CASE berücksichtigt hast, erwartest Du also von Deinem DBMS, dass es dann nicht 1 und auch nicht 1.25, sondern irgendetwas anderes zurückgibt ... aber was? Du solltest also noch einen ELSE-Zweig einbauen.
Trotz alledem kann man suit aber eigentlich nur Recht geben: ein VARCHAR-Feld zu nehmen und dort Strings, die Zahlenwerte enthalten, zu speichern und dann mit einem derartigen CASE-Konstrukt einen Multiplikator zu ermitteln ist gelinde gesagt wirklich "von hinten durch die Brust ins Auge".
Ich habe mich sicher falsch ausgedrückt. Aber die Sache ist so:
Tabelle Artikel:
ID|Warenkorb_ID|Menge|Preis|Nachlass|Multi|...Tabelle Warenkorb:
ID|User_ID|Datum|Warenkorb_Nachlass|...
Aha ... und jetzt? Wo genau möchtest Du jetzt wieviel Rabatt/Nachlass gewähren? Du solltest nicht nur die Namen der Spalten, sondern auch ihre Datentypen nennen und zusätzlich einige Beispieldatensätze (beider Tabellen!), damit man nachvollziehen kann, was Du hast und was Du erreichen willst.
MfG,
EKKi
Hi EKKi,
Du schriebst, dass in der Spalte "Multi" noch weitere Werte enthalten sein können. Da Du diese nicht in Deinem CASE berücksichtigt hast, erwartest Du also von Deinem DBMS, dass es dann nicht 1 und auch nicht 1.25, sondern irgendetwas anderes zurückgibt ... aber was? Du solltest also noch einen ELSE-Zweig einbauen.
Es gibt nur 6 Möglichkeiten und die habe ich alle erfasst. Deshalb habe ich auf das ELSE verzichtet. Ist das falsch?
Ich habe mich sicher falsch ausgedrückt. Aber die Sache ist so:
Tabelle Artikel:
ID|Warenkorb_ID|Menge|Preis|Nachlass|Multi|...Tabelle Warenkorb:
ID|User_ID|Datum|Warenkorb_Nachlass|...Aha ... und jetzt? Wo genau möchtest Du jetzt wieviel Rabatt/Nachlass gewähren?
Innerhalb der Tabelle 'Artikel' können Nachlässe stehen, in der float-Spalte mit dem Namen 'Nachlass'.
Diese Artikelnachlässe werden ja bereits berücksichtigt in miener Abfrage.
Zusätzlich können in der Tabelle 'Warenkorb' in der float-Spalte 'Warenkorb_Nachlass' Gesamtnachlässe für alle Artikel enthalten sein, die in diesem Warenkorb (gekennzeichnet über Artikel.Warenkorb_ID=Warenkorb.ID) enthalten sind.
Grüße,Fletch
Tach,
Es gibt nur 6 Möglichkeiten und die habe ich alle erfasst. Deshalb habe ich auf das ELSE verzichtet. Ist das falsch?
noch nicht, allerdings würde es mich nerven, nur weil sich die Daten in der Datenbank ändern an der Logik rumbasteln zu müssen.
mfg
Woodfighter
Hallo,
Warum denn gleich einen Seitehieb auf mich?
Nicht wundern, das ist üblich hier. Für manch einen ist das die einzige Möglichkeit sein fragiles Ego aufzupolieren. Du kannst kein Komma verschieben? Bist du in der Pupertät hängengeblieben? Selbst mein drei Jahre alter Änkelsohn konnte das schon mit zwei.. bla blub die selbe alte Leier..
Gruß,
Manuel
PS: Die Rechtschreibfehler habe ich euch zu Liebe absichtlich eingebaut, damit ihr sofort ein "Totschlag-Argument" gegen meine Aussage habt.
PPS: Und, um es euch noch leichter zu machen, habe ich auch gleich absichtlich unter einer Sockenpuppe geantwortet.. damit könnt ihr mir dann den Rest geben.
samefag :p
Also mir gefaellt der Änkelsohn. Sieht nett aus.