komplexe UDF - mysql

DaSuckOOr

Mitglied
hi,

ich wollte fragen ob folgendes Szenario über eine udf abhandelbar ist.

ich übergebe an die udf ein ?array? aus Datums-Werten (01.03.2013, 02.03.2013, 03.03.2013) und einer userID (bspw. 40)
jetzt soll die udf aus einer Tabelle den status auslesen
Beispiel der Tabelle:

userID datum status
40 01.03.2013 1
40 02.03.2013 2

der jeweilige status soll dann zurückgegeben werden (in diesem Bsp. 1 und 2)

derzeit löse ich das Ganze in php. Schöner wäre es allerdings in mysql, da habe ich dann alles kompakt und tu mich mit dem sortieren und einschränken leichter.

Danke!

Gruß
 
Du kannst es ausnutzen, dass MySQL das Datum zu einem String formatieren Dann kannst du in PHP alle deine Daten mit einem Komma aneinander reihen und als einen String MySQL übergeben. Diesen kannst du dort mit FIND_IN_SET() verarbeiten

SQL:
SELECT 
	user_id,
	datum,
	`status`
FROM 
	my_table
WHERE
	-- Den letzten String auf der folgenden Zeile von PHP übergeben
	FIND_IN_SET(DATE_FORMAT(datum, '%d.%m.%Y'), '04.01.2010,05.01.2010')
	AND userid = 40;
 
Zuletzt bearbeitet von einem Moderator:
danke für deine Antwort!

ich will es an der Stelle noch ein bisschen komplizierter treiben :)

und zwar habe ich drei stati (1: verfügbar, 2: auf Anfrage, 3: gebucht)

Fall1: wenn er jetzt zu einem Datum den Status 3 (gebucht) ermittelt, soll auch 3 zurückgegeben werden
Fall2: wenn alle übergebenen Datumswerte Status 1 (verfügbar) sind, dann soll 1 zurückgegeben werden
Fall3: ansonsten immer 2 zurückgeben.

das Ganze sollte sich aber in einem select statement aufrufen lassen, da ich (wie es der User wünscht) nach 1,2 oder 3 einschränken will
 
Dann gibt es also nicht zu jedem ausgewählten Datum ein Eintrag in der DB?

Wieviele Datum können maximal mitgegeben werden?
 
genau, nicht zu jedem Datum existiert ein Eintrag.

das Ganze ist Teil eines Buchungsskriptes man soll schon einen Zeitraum von 4 Wochen mitgeben können (unwahrscheinlicher Fall, aber möglich) d.h. 28 Datum
 
28 Zeilen. Jepp, damit lässts sichs leben *g*

Als erstes müssen wir für jeden Eintrag in der Liste eine Zeile erstellen
Ich habe dazu mein Script MySQL Virtuelle Tabelle mit allen Daten eines Monats etwas angepasst
SQL:
-- Simulation des Listenstrings aus PHP
SET @date_list = '10.01.2010,15.01.2010,04.02.2010';

SELECT
   -- Datum um einen Tag hochzählen
   @act_date := DATE_ADD(@act_date, INTERVAL 1 DAY) AS mydate
FROM
   -- 6^2 Zeilen erstellen: Also 36.
   (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6) AS d1,
   (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6) AS d2,
   -- Variablen instanzieren
	-- Das erste Datum der Liste extrahieren und um einen Tag reduszieren, da nachher wieder einer dazugezählt wird
   (SELECT @act_date :=  DATE_SUB(STR_TO_DATE(LEFT(@date_list, 10), '%d.%m.%Y'),INTERVAL 1 DAY)) AS vars
HAVING
	FIND_IN_SET(DATE_FORMAT(mydate, '%d.%m.%Y'), @date_list)

Und das können wir jetzt noch locker mit einem LEFT JOIN verbinden und mit einem CASE WHEN die Bedienungen einbauen. Mit IFNULL() noch sicherstellen dass bei fehlenden Einträgen der Status 2 gesetzt ist.
SQL:
-- Simulation des Listenstrings aus PHP.
SET @date_list = '10.01.2010,15.01.2010,04.02.2010';

SELECT
	d.mydate,
	-- Wenn kein Status verfügbar ist, da kein Eintrag vorhanden ist, nimm die 2
	CASE IFNULL(t.status, 2)
		WHEN 1 THEN 'verfügbar'
		WHEN 2 THEN 'auf Anfrage'
		WHEN 3 THEN 'gebucht'
		ELSE 'n/a'
	END AS status_text
FROM
	(
		SELECT
		   -- Datum um einen Tag hochzählen
		   @act_date := DATE_ADD(@act_date, INTERVAL 1 DAY) AS mydate
		FROM
		   -- 6^2 Zeilen erstellen: Also 36.
		   (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6) AS d1,
		   (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6) AS d2,
		   -- Variablen instanzieren
			-- Das erste Datum der Liste extrahieren und um einen Tag reduszieren, da nachher wieder einer dazugezählt wird
		   (SELECT @act_date :=  DATE_SUB(STR_TO_DATE(LEFT(@date_list, 10), '%d.%m.%Y'),INTERVAL 1 DAY)) AS vars
		HAVING
			FIND_IN_SET(DATE_FORMAT(mydate, '%d.%m.%Y'), @date_list)
	) AS d
	LEFT JOIN (
		SELECT * FROM my_table WHERE userid = 40
	) AS t
		ON d.mydate = t.date

Du musst jetzt nur noch die erste Zeile mit dem SET weglassen und in PHP die @date_list durch deine Datenliste sowie die 40 durch deine ID ersetzen.
Sollte nicht mehr so schwer sein.

Das ganze ist wie immer ungetestet und ohne gewähr
 
Zuletzt bearbeitet von einem Moderator:
Zurück