Privatrolf
2008-05-15, 16:14:48
Ahoi.
Ich habe quasi Arrays in einer MySQL-Tabelle. Da MySQL Arrays nicht nativ unterstützt, habe ich mich für einen String aus IDs mit Trennzeichen entschieden. Hierbei fällt relativ viel dumpfe Stringverarbeitung an, und vieles davon auch noch mehrfach wiederholt pro Statement.
Ich bin in Sachen SQL noch ziemlich grün hinter den Ohren, aber ich kann mir nicht vorstellen dass das besonders effizient ist. Ich frage mich nun ob es möglich ist, Teilergebnisse in einem SELECT-Statement zwischenzuspeichern und noch im gleichen Statement wiederzuverwenden, quasi analog zu temporären Variablen in Programmiersprachen.
Ich habe zB in bestimmten Situationen Lindwurm-Queries folgender Form:UPDATE content_cats SET `show`=TRIM(':' FROM
CONCAT_WS(':',NULLIF(SUBSTRING_INDEX(
CONCAT(':',`show`,':'),NULLIF(CONCAT(
':',SUBSTRING_INDEX(SUBSTRING_INDEX(
CONCAT(':',`show`,':'),':17:',1),':',-1),':'),'::'),1),''),'17',
NULLIF(SUBSTRING_INDEX(SUBSTRING_INDEX(
CONCAT(':',`show`,':'),':17:',1),':',-1),''),SUBSTRING_INDEX(
CONCAT(':',`show`,':'),':17:',-1)))
WHERE `cat`='' AND LOCATE(':17:',CONCAT(`show`,':'))!=0
Hier noch der PHP-Code der mir dieses Ding erzeugt hat:<?php
$ref='17';
$mref="'".":$ref:"."'";
$pre_ref="SUBSTRING_INDEX(CONCAT(':',`show`,':'),".$mref.",1)";
$post_ref="SUBSTRING_INDEX(CONCAT(':',`show`,':'),".$mref.",-1)";
$displaced="SUBSTRING_INDEX(".$pre_ref.",':',-1)";
$pre_displaced="SUBSTRING_INDEX(CONCAT(':',`show`,':'),NULLIF(CONCAT(':',".$displaced.",':'),'::'),1)";
$qc="UPDATE nodyn_content_cats SET `show`=".
"TRIM(':' FROM CONCAT_WS(':',NULLIF(".$pre_displaced.",''),'".$ref."',".
"NULLIF(".$displaced.",''),".$post_ref."))".
" WHERE `cat`='".$cat."' AND ".
"LOCATE('".":$ref:"."',CONCAT(`show`,':'))!=0";
print_r($qc);
?>Das muss alles in einem Rutsch durch. Ich wil Atomizität sicherstellen, und da ich PHP nutze, habe ich auch keine Möglichkeit mehrere Statements zu verketten. In einer (Heap-)Tabelle explizit cachen möchte ich nicht. Das wäre wohl noch weniger elegant (und noch weniger effizient).
Wie man nun im PHP-Code erkennt gibt es da bestimmte Unterterme die mehrfach vorkommen. Diese würde ich gerne nur einmal erzeugen und in Variablen ablegen, um sie dann im weiteren Verlauf der Query "einfach" wieder abrufen zu können. Falls das irgendwie geht.
Ich habe quasi Arrays in einer MySQL-Tabelle. Da MySQL Arrays nicht nativ unterstützt, habe ich mich für einen String aus IDs mit Trennzeichen entschieden. Hierbei fällt relativ viel dumpfe Stringverarbeitung an, und vieles davon auch noch mehrfach wiederholt pro Statement.
Ich bin in Sachen SQL noch ziemlich grün hinter den Ohren, aber ich kann mir nicht vorstellen dass das besonders effizient ist. Ich frage mich nun ob es möglich ist, Teilergebnisse in einem SELECT-Statement zwischenzuspeichern und noch im gleichen Statement wiederzuverwenden, quasi analog zu temporären Variablen in Programmiersprachen.
Ich habe zB in bestimmten Situationen Lindwurm-Queries folgender Form:UPDATE content_cats SET `show`=TRIM(':' FROM
CONCAT_WS(':',NULLIF(SUBSTRING_INDEX(
CONCAT(':',`show`,':'),NULLIF(CONCAT(
':',SUBSTRING_INDEX(SUBSTRING_INDEX(
CONCAT(':',`show`,':'),':17:',1),':',-1),':'),'::'),1),''),'17',
NULLIF(SUBSTRING_INDEX(SUBSTRING_INDEX(
CONCAT(':',`show`,':'),':17:',1),':',-1),''),SUBSTRING_INDEX(
CONCAT(':',`show`,':'),':17:',-1)))
WHERE `cat`='' AND LOCATE(':17:',CONCAT(`show`,':'))!=0
Hier noch der PHP-Code der mir dieses Ding erzeugt hat:<?php
$ref='17';
$mref="'".":$ref:"."'";
$pre_ref="SUBSTRING_INDEX(CONCAT(':',`show`,':'),".$mref.",1)";
$post_ref="SUBSTRING_INDEX(CONCAT(':',`show`,':'),".$mref.",-1)";
$displaced="SUBSTRING_INDEX(".$pre_ref.",':',-1)";
$pre_displaced="SUBSTRING_INDEX(CONCAT(':',`show`,':'),NULLIF(CONCAT(':',".$displaced.",':'),'::'),1)";
$qc="UPDATE nodyn_content_cats SET `show`=".
"TRIM(':' FROM CONCAT_WS(':',NULLIF(".$pre_displaced.",''),'".$ref."',".
"NULLIF(".$displaced.",''),".$post_ref."))".
" WHERE `cat`='".$cat."' AND ".
"LOCATE('".":$ref:"."',CONCAT(`show`,':'))!=0";
print_r($qc);
?>Das muss alles in einem Rutsch durch. Ich wil Atomizität sicherstellen, und da ich PHP nutze, habe ich auch keine Möglichkeit mehrere Statements zu verketten. In einer (Heap-)Tabelle explizit cachen möchte ich nicht. Das wäre wohl noch weniger elegant (und noch weniger effizient).
Wie man nun im PHP-Code erkennt gibt es da bestimmte Unterterme die mehrfach vorkommen. Diese würde ich gerne nur einmal erzeugen und in Variablen ablegen, um sie dann im weiteren Verlauf der Query "einfach" wieder abrufen zu können. Falls das irgendwie geht.