Formel für % ausrechnen

Hallo,

ich möchte gerne herausfinden wie viel % der Einträge mit meiner Datenbank übereinstimmen.

In der Datenbank gibt es 5 Einträge: Apfel, Birne, Bananne, Kiwi, Mango.

Der Warenkorb der Benutzer enthält: Apfel, Kiwi, Mango
Wenn alle Früchte vorhanden sind, erhält er 100% und wenn kein Frucht vorhanden ist, erhält er 0%.

Wenn also wie in diesem Beispiel 3 Früchte im Warenkorb existieren, könnte ich 100 - (100 / 3) ausrechnen und das ergibt dann 67%. So, aber was jetzt wenn er nur ein Apfel haben will? 100 - (100 / 1) wäre dann 0%.

Ich denke meine Formel macht irgendwie generell keinen Sinn. Wäre froh, wenn mir jemand dabei weiterhelfen würde.
 
@RezaScript Denk Dir nichts, das geht jedem mal so, sonst wäre es ja langweilig :)

Du kannst das auch aus der DB abfragen:
SQL:
-- Die Division durch 3, weil es 3 Suchbegriffe sind
SELECT count(distinct sorte) / 3 FROM obst WHERE sorte in ('Apfel', 'Kiwi', 'Mango');
 
@mihe7 gut zu wissen, danke dir!

@Tobias-nrw der Code ist einfach. Sieht einfach so aus: ($match / $countedItems) * 100;
Falls dir der gesamte Code interessiert:
PHP:
private function countVotedItems(string $table, string $column) {
    $result = array();
    $countedItems = count($this->userInput[$column]);

    // Go through each user
    foreach ($this->users as $user) {
        $subtotal = array();
        // Go through each item
        foreach ($this->userInput[$column] as $item) {
            // Get the query
            $query = null;
            try {
                $query = $this->matchDao->rawSQL(/** @lang text */ "SELECT uid, tech, vote FROM $table WHERE tech = '$item' AND uid = '$user'");

            }
            catch (DBALException $e) {
                // var_dump($e);
            }
            // If the query could be found, add it to subtotal
            if ($query) {
                array_push($subtotal, 1);
            }
            else {
                array_push($subtotal, 0);
            }
        }

        // Find out how many matches they are
        $match = $countedItems;
        foreach ($subtotal as $value) {
            if ($value == 0) {
                $match--;
            }
        }
        // Formula: (founded matches / all existing items) * 100
        $result[$user] = ($match / $countedItems) * 100;
    }
    return $result;
}
 
Bei dem Code fehlen mir schon fast die Worte...

Das ganze ist eine wandelnde Sicherheitslücke: SQL-Injections lassen grüßen. Bitte lass das nicht online erreichbar sein!

Das ganze ist höllisch ineffizient: du stellst für jeden Nutzer für jedes Listenelement eine eigene SQL-Anfrage (höllisch langsam) und zum aufsummieren speicherst du 1/0 in einer Liste, und iterierst danach über die Liste und prüfst, ob es eine 1 ist (im Verhältnis zur SQL-Anfrage nicht relevant, aber wie kommt man überhaupt auf solche Ideen?


Wie das vernünftig geht, hat @mihe7 ja schon gezeigt, das lässt sich auch mit den Nutzern kombinieren. Das ganze kannst du damit reduzieren auf genau eine SQL-Abfrage und eine Schleife, die schlicht über das Ergebnis iteriert um das in ein dir passendes Format zu bringen.
 
@mrBrown was die Performance angeht, bin ich völlig mit dir einverstanden. Den Code muss ich noch überarbeiten. Aber was hat das jetzt alles mit dem SQL-Injection an sich? Alle Variablen wie $table, $item und $user werden vorher validiert.
 
Wie wurde das denn validiert?

Und selbst wenn das korrekt gemacht wurde: es gibt kaum einen vernünftigen Grund, nicht trotzdem Prepared Statements zu nutzen - die sollten immer erste Wahl sein (in Verbindung mit WhiteLists für die Dinge, die keine Parameter sind)
 
Wie wurde das denn validiert?
$table ist nur ein String, welcher nur von mir eingegeben wird und nicht vom Benutzer. Und die anderen zwei Variablen werden von anderen Klassen validiert. Der Prozess ist also lang, damit der User überhaupt zu diesem Query kommt.

Und selbst wenn das korrekt gemacht wurde: es gibt kaum einen vernünftigen Grund, nicht trotzdem Prepared Statements zu nutzen - die sollten immer erste Wahl sein (in Verbindung mit WhiteLists für die Dinge, die keine Parameter sind)
Ich habe selbst versucht ein SQL-Injection durchzuführen und ich bin daran gescheitert. Ich denke das liegt daran, dass auf meinem Server magic_quotes_gpc auf off gestellt ist. Ich verstehe aber deinen Punkt, dass es wichtig ist und nehme es gerne zur Kenntnis.
 
K

kneitzel

Also dein item wird aber doch dynamisch sein, also dabei wird es sich doch um die Namen vom Obst und so handeln. Was, wenn der Benutzer da nun etwas anlegt, das ein Quote Zeichen beinhaltet?

Selbst wenn jetzt im Augenblick etwas ausgeschlossen ist: Das ist eine Komplexität, die versteckt ist und eine wichtige Abhängigkeit, die auch nicht dokumentiert und ersichtlich ist. Und das auch garantiert nicht Unit getestet ist. ==> Die Gefahr ist also gegeben, dass spätere Versionen verwundbar werden.

Also hoffentlich wird so schnell deutlich, dass dies etwas ist, das man so doch niemals machen sollte, wenn es vermeidbar ist.
 
K

kneitzel

@RezaScript Hör nicht auf den Quatsch, sondern nutze einfach:
PHP:
mysql_real_escape_string(userInput[$column]));
.
Das ist der "php weg" für sowas? Das ist die Lösung für ein Problem, welches es eigentlich gar nicht gibt da man ja einfach nur sorgfältig arbeiten müsste oder so ähnlich.

Und wie sieht die Lösung aus bezüglich unterschiedlicher Darstellung von Werten? Dann funktioniert die Applikation nicht, wenn Datenbank und Applikation unterschiedliche Einstellungen haben? Und zumindest ist die Typsicherheit komplett für die Katz'.

Localization and Globalization sind da die Stichworte, die wichtig sind und über die man etwas mehr nachdenken sollte, wenn man eine Applikation schreibt.

Ich würde solch Dinge als fundamental im Bereich der Applikationsentwicklung bezeichnen....
 
K

kneitzel

Also dass es Fälle gibt, in denen Parameter nicht genutzt werden können, ist klar. Das kann z.B. der Fall sein, wenn man Felder dynamisch ansprechen will oder generell bei DDE. Aber da ist das auch nicht der in meinen Augen gewünschte Weg, denn beim Datenbank Design will ich in der Regel keine Namen mit speziellen Zeichen auch wenn dies prinzipiell gehen würde.

Und mag sein, dass StackOverflow dies als eine Option bringt, aber ich bezweifle sehr, dass es dies als bevorzugte Lösung zeigt (es sei denn, es ging um einen Fall, in dem es nicht anders geht...)

Aber zeig uns den SO Beitrag einfach einmal. Wir lernen auch gerne dazu...
 
Man könnte argumentieren, dass die Geschwindigkeit einer direkten Abfrage höher ist, weil die Schritte für die Vorbereitung und das Setzen der Parameter entfallen. Da prepared Statements in der Regel wiederverwendet werden, greift dieses Argument aber nur für einmalige Abfragen. Bei diesen fällt der zusätzliche Schritt zeitlich jedoch nicht merklich ins Gewicht.

Das kann z.B. der Fall sein, wenn man Felder dynamisch ansprechen
Wie meinst Du das?
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben