it-swarm.com.de

Wie werden zwei ausgewählte Abfragen zu RSForm-Übermittlungsdaten refaktorisiert?

Ich habe mich gefragt, ob mir jemand helfen kann, mehrere Abfragen zu einer Abfrage zusammenzufassen. Derzeit rufen diese beiden Codeblöcke Informationen aus der Datenbank ab. Ich benutze das "Sourcerer" -Plugin, um benutzerdefinierten PHP Code in mein benutzerdefiniertes Modul einzufügen.

Die vollständige Abfrage ist jedoch viel zu lang, und ich muss die Größe erheblich reduzieren. Nach einer bestimmten Anzahl von Abfragen wird die Seite überhaupt nicht geladen.

Ich werde zwei Fragen stellen, die ich als Beispiel hinzugefügt haben muss.

<?php 
$db = JFactory::getDbo();
$db->getQuery(true);

$db->setQuery("SELECT `SubmissionId`, `FieldValue`, `FormId` FROM `jos_rsform_submission_values` WHERE `FieldName` = \"Status1\" AND `FieldValue` = \"Pending\" AND `FormId` = 28");
$results = $db->loadColumn();

$db->getQuery(true);
$db->setQuery("SELECT `FieldValue` FROM `jos_rsform_submission_values` WHERE `FieldName` = \"Container1\" AND `SubmissionId` IN ('".implode("', '", $results)."') ORDER BY `jos_rsform_submission_values`.`SubmissionId`"); 

$result = $db->loadObjectList();

foreach($result as $value) {
    foreach($value as $key => $data) { 
        echo $data."<br />"; 
    }
}
?>
1
MailBlade

Ich glaube, dass die mySQL-Abfrage durch (1,2,3) ersetzt wird, um die Ergebnisse zu implodieren, da ich die mySql-Syntax überprüfen wollte. Ich habe momentan keine Zeit zum Konvertieren in PHP), wollte aber versuchen zu helfen. Wenn es nicht funktioniert, lass es mich in Kommentaren wissen und ich werde versuchen, Folgendes anzupassen:

SELECT a.FieldValue as Container, b.FieldValue as ContainerType FROM ( SELECT FieldValue FROM jos_rsform_submission_values WHERE FieldName = "Container1" AND SubmissionId IN (1,2,3)) as a LEFT JOIN ( SELECT FieldValue FROM jos_rsform_submission_values WHERE FieldName = "containertype1" AND SubmissionId IN (1,2,3)) as b on a.SubmissionId = b.SubmissionId ORDER BY a.SubmissionId;

Ich musste die Häkchen entfernen, damit StackExchange korrekt formatiert wurde, aber ich würde vorschlagen, Ihren Code so zu konvertieren, dass stattdessen ohnehin $ db-> quote und $ dbquotename verwendet werden: https: //docs.joomla .org/Selecting_data_using_JDatabase
https://docs.joomla.org/Secure_coding_guidelines

2
YellowWebMonkey

Ja, Ihre Anfragen können sicherlich Refactoring verwenden. Durch die Verwendung von zwei separaten Aufrufen für dieselbe Tabelle wird MySQL aufgefordert, unnötige zusätzliche Arbeit zu leisten.

Um Ihre Abfragen in einfaches Englisch umzuwandeln, möchten Sie:

  • erstellen Sie eine Ergebnismenge von containertype1 - Werten, sortiert nach SubmissionId
  • für jedes SubmissionId aus FormId28
  • einschließlich nur der Einreichungen, die den Wert Status1 von Pending enthalten.

Die sauberste und direkteste Art, diese Aufgabe auszuführen, ist die Pivot-Technik.

Rohdatenabfrage (ungetestet):

SELECT
    MAX(CASE WHEN FieldName = 'containertype1' THEN FieldValue ELSE NULL END)
FROM `#__rsform_submission_values`
WHERE FormId = 28
GROUP BY SubmissionId
HAVING MAX(CASE WHEN FieldName = 'Status1' THEN FieldValue ELSE NULL END) = 'Pending'
ORDER BY SubmissionId

GROUP BY Erstellt "aggregierte Daten" für jedes eindeutige SubmissionId. Das Extrahieren bestimmter Details aus dieser Sammlung konsolidierter Zeilen erfordert spezielle Aufrufe (z. B. MAX(CASE...)).

Die HAVING -Klausel erfordert, dass SubmissionIds eine Zeile mit einem FieldName von Status1 Und einem FieldValue -Wert von Pending enthält. Dies beruht auf der Tatsache, dass Ihre Tabelle "submission_values" nicht zulässt, dass eine SubmissionId 2 oder mehr Zeilen Status1 Enthält.

Für jede qualifizierte SubmissionId liefert die Ergebnismenge den Wert, der mit containertype1 Gespeichert wird. Wenn die qualifizierende SubmissionId keine containertype1 - Zeile enthält, wird standardmäßig ein NULL -Wert angegeben (Sie können NULL in No Container Type Ändern, wenn Sie dies wünschen ).

PHP/Joomla Syntax (ungetestet):

$query = $db->getQuery(true)
    ->select("MAX(CASE WHEN FieldName = 'containertype1' THEN FieldValue ELSE NULL END)")
    ->from("#__rsform_submission_values")
    ->where("FormId = 28")
    ->group("SubmissionId")
    ->having("MAX(CASE WHEN FieldName = " . $db->q("status") . " THEN FieldValue ELSE NULL END) = " . $db->q("pending"));

// echo $query->dump();  // uncomment if you want to confirm the rendered query
try {
    $db->setQuery($query);
    echo "<pre>";
    var_dump($db->loadColumn());
} catch (Exception $e) {
    JFactory::getApplication()->enqueueMessage("Query Syntax Error: " . $e->getMessage(), 'error');  // never show getMessage() to public
}

Wenn Sie diese Technik in anderen Zusammenhängen sehen möchten, sind hier einige andere Pivot-Lösungen, die ich veröffentlicht habe:

1
mickmackusa