Export erstellt am: 2026-05-24 12:21:30 Datenbank: ga Version: 8.4.8 ==================== ROW COUNTS ==================== umsaetze : 11605 umsatz_split : 18 kategorie_parts : 1200 kat_part_link : 1185 kategorien : 54 v_umsaetze : 11616 ==================== SHOW CREATE TABLE umsaetze ==================== CREATE TABLE `umsaetze` ( `pos` int NOT NULL, `betrag` decimal(15,2) DEFAULT NULL, `buchtext` varchar(500) DEFAULT NULL, `valutaStr` varchar(12) DEFAULT NULL, `valuta` date DEFAULT NULL, `unique_id` varchar(100) NOT NULL, `kategorie` varchar(50) DEFAULT NULL, `werte` varchar(1000) DEFAULT NULL, `info` varchar(1000) DEFAULT NULL, `importstmp` timestamp NULL DEFAULT CURRENT_TIMESTAMP, `kategorie_new` varchar(2000) DEFAULT NULL, `abw_valuta` date DEFAULT NULL, `abw_buchtext` varchar(1000) DEFAULT NULL, `hinweis` varchar(1000) DEFAULT NULL, `old_uid` varchar(255) DEFAULT NULL, `valuta_eff` date GENERATED ALWAYS AS (coalesce(`abw_valuta`,`valuta`)) STORED, `match_buchtext` text, `match_buchtext_norm` text, UNIQUE KEY `pos` (`pos`), UNIQUE KEY `unique_id` (`unique_id`), KEY `idx_id` (`pos`), KEY `idx_umsaetze_valuta_eff` (`valuta_eff`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; ==================== SHOW CREATE TABLE umsatz_split ==================== CREATE TABLE `umsatz_split` ( `split_id` int NOT NULL AUTO_INCREMENT, `parent_pos` int NOT NULL, `abw_valuta` date DEFAULT NULL, `betrag` decimal(12,2) NOT NULL, `kategorie` int DEFAULT NULL, `buchtext` varchar(700) DEFAULT NULL, `sort_order` int NOT NULL DEFAULT '1', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `abw_buchtext` text, PRIMARY KEY (`split_id`), KEY `idx_parent` (`parent_pos`) ) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; ==================== SHOW CREATE TABLE kategorie_parts ==================== CREATE TABLE `kategorie_parts` ( `name` varchar(2000) DEFAULT NULL, `part_id` int NOT NULL AUTO_INCREMENT, `abw_prio` int DEFAULT NULL, `match_part` varchar(2000) DEFAULT NULL, `match_part_norm` varchar(2000) DEFAULT NULL, `match_anchor` varchar(255) DEFAULT NULL, PRIMARY KEY (`part_id`), KEY `idx_match_anchor` (`match_anchor`(100)) ) ENGINE=InnoDB AUTO_INCREMENT=1209 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='.. ABW_PRIO=wird brei prioritätsermittlung hinzugezählt um einsilibige parts höher zu priorisieren'; ==================== SHOW CREATE TABLE kat_part_link ==================== CREATE TABLE `kat_part_link` ( `part_id` int NOT NULL, `kategorie_id` int DEFAULT NULL, UNIQUE KEY `idx_part_kat` (`part_id`,`kategorie_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; ==================== SHOW CREATE TABLE kategorien ==================== CREATE TABLE `kategorien` ( `kategorie_id` int NOT NULL AUTO_INCREMENT, `name` varchar(700) DEFAULT NULL, `abw_kat_kz` int DEFAULT NULL, `notiz_vorlage` mediumtext, PRIMARY KEY (`kategorie_id`), UNIQUE KEY `name` (`name`) ) ENGINE=InnoDB AUTO_INCREMENT=56 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='abw_kat_kz=kategorien, die nicht automatisch zugeordnet werden. ist für z.b. umbuchunge, hausverkauf .'; ==================== SHOW CREATE VIEW v_umsaetze ==================== CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`%` SQL SECURITY DEFINER VIEW `v_umsaetze` AS select `u`.`pos` AS `pos`,`u`.`betrag` AS `betrag`,coalesce(`u`.`abw_buchtext`,`u`.`buchtext`) AS `buchtext`,`u`.`valutaStr` AS `valutaStr`,`u`.`valuta` AS `valuta`,`u`.`unique_id` AS `unique_id`,`u`.`kategorie` AS `kategorie`,`u`.`werte` AS `werte`,`u`.`info` AS `info`,`u`.`importstmp` AS `importstmp`,`u`.`kategorie_new` AS `kategorie_new`,`u`.`abw_valuta` AS `abw_valuta`,`u`.`abw_buchtext` AS `abw_buchtext`,`u`.`hinweis` AS `hinweis`,`u`.`old_uid` AS `old_uid`,`u`.`valuta_eff` AS `valuta_eff`,`u`.`match_buchtext` AS `match_buchtext`,`u`.`match_buchtext_norm` AS `match_buchtext_norm`,0 AS `is_split`,0 AS `has_splits`,`u`.`pos` AS `parent_pos`,0 AS `split_id`,0 AS `sort_order` from (`umsaetze` `u` left join `umsatz_split` `s` on((`s`.`parent_pos` = `u`.`pos`))) where (`s`.`parent_pos` is null) union all select -(((`u`.`pos` * 1000000) + `s`.`split_id`)) AS `pos`,`s`.`betrag` AS `betrag`,coalesce(`s`.`abw_buchtext`,`u`.`abw_buchtext`,`s`.`buchtext`,`u`.`buchtext`) AS `buchtext`,`u`.`valutaStr` AS `valutaStr`,`u`.`valuta` AS `valuta`,`u`.`unique_id` AS `unique_id`,coalesce(`s`.`kategorie`,`u`.`kategorie`) AS `kategorie`,`u`.`werte` AS `werte`,`u`.`info` AS `info`,`u`.`importstmp` AS `importstmp`,`u`.`kategorie_new` AS `kategorie_new`,coalesce(`s`.`abw_valuta`,`u`.`abw_valuta`) AS `abw_valuta`,coalesce(`s`.`abw_buchtext`,`u`.`abw_buchtext`) AS `abw_buchtext`,`u`.`hinweis` AS `hinweis`,`u`.`old_uid` AS `old_uid`,`u`.`valuta_eff` AS `valuta_eff`,trim(concat_ws(' ',nullif(trim(coalesce(`s`.`buchtext`,`u`.`buchtext`)),''),nullif(trim(coalesce(`s`.`abw_buchtext`,`u`.`abw_buchtext`)),''))) AS `match_buchtext`,trim(replace(replace(replace(replace(replace(replace(replace(replace(lower(concat(' ',trim(concat_ws(' ',nullif(trim(coalesce(`s`.`buchtext`,`u`.`buchtext`)),''),nullif(trim(coalesce(`s`.`abw_buchtext`,`u`.`abw_buchtext`)),''))),' ')),',',' '),'.',' '),'-',' '),'/',' '),';',' '),':',' '),'straße','str'),'str.','str')) AS `match_buchtext_norm`,1 AS `is_split`,1 AS `has_splits`,`u`.`pos` AS `parent_pos`,`s`.`split_id` AS `split_id`,`s`.`sort_order` AS `sort_order` from (`umsaetze` `u` join `umsatz_split` `s` on((`s`.`parent_pos` = `u`.`pos`))); ==================== TRIGGERS ==================== Trigger: trigger_updt_time06 Tabelle: kat_part_link Event: INSERT Timing: AFTER Statement: update ga.last_import_date set stmp = sysdate() where stmp is not null Trigger: trigger_updt_time07 Tabelle: kat_part_link Event: UPDATE Timing: AFTER Statement: update ga.last_import_date set stmp = sysdate() where stmp is not null Trigger: trigger_updt_time08 Tabelle: kat_part_link Event: DELETE Timing: AFTER Statement: update ga.last_import_date set stmp = sysdate() where stmp is not null Trigger: kp_match_anchor_bi Tabelle: kategorie_parts Event: INSERT Timing: BEFORE Statement: SET NEW.match_anchor = LOWER( TRIM( REPLACE( SUBSTRING_INDEX(NEW.name, ',', 1), '_', ' ' ) ) ) Trigger: kp_match_anchor_bu Tabelle: kategorie_parts Event: UPDATE Timing: BEFORE Statement: SET NEW.match_anchor = LOWER( TRIM( REPLACE( SUBSTRING_INDEX(NEW.name, ',', 1), '_', ' ' ) ) ) Trigger: kp_match_part_bi Tabelle: kategorie_parts Event: INSERT Timing: BEFORE Statement: SET NEW.match_part = LOWER( REPLACE( TRIM(NEW.name), '_', ' ' ) ) Trigger: kp_match_part_bu Tabelle: kategorie_parts Event: UPDATE Timing: BEFORE Statement: SET NEW.match_part = LOWER( REPLACE( TRIM(NEW.name), '_', ' ' ) ) Trigger: kp_prepare_bi Tabelle: kategorie_parts Event: INSERT Timing: BEFORE Statement: BEGIN SET NEW.match_part = LOWER(REPLACE(TRIM(COALESCE(NEW.name, '')), '_', ' ')); SET NEW.match_part_norm = TRIM( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( LOWER(CONCAT(' ', REPLACE(TRIM(COALESCE(NEW.name, '')), '_', ' '), ' ')), '.', ' ' ), '-', ' ' ), '/', ' ' ), ';', ' ' ), ':', ' ' ), 'straße', 'str' ) ); SET NEW.match_part_norm = REPLACE(NEW.match_part_norm, 'str.', 'str'); WHILE INSTR(NEW.match_part_norm, ' ') > 0 DO SET NEW.match_part_norm = REPLACE(NEW.match_part_norm, ' ', ' '); END WHILE; SET NEW.match_anchor = LOWER( SUBSTRING_INDEX( TRIM( REPLACE( SUBSTRING_INDEX(COALESCE(NEW.name, ''), ',', 1), '_', ' ' ) ), ' ', 1 ) ); END Trigger: kp_prepare_bu Tabelle: kategorie_parts Event: UPDATE Timing: BEFORE Statement: BEGIN SET NEW.match_part = LOWER(REPLACE(TRIM(COALESCE(NEW.name, '')), '_', ' ')); SET NEW.match_part_norm = TRIM( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( LOWER(CONCAT(' ', REPLACE(TRIM(COALESCE(NEW.name, '')), '_', ' '), ' ')), '.', ' ' ), '-', ' ' ), '/', ' ' ), ';', ' ' ), ':', ' ' ), 'straße', 'str' ) ); SET NEW.match_part_norm = REPLACE(NEW.match_part_norm, 'str.', 'str'); WHILE INSTR(NEW.match_part_norm, ' ') > 0 DO SET NEW.match_part_norm = REPLACE(NEW.match_part_norm, ' ', ' '); END WHILE; SET NEW.match_anchor = LOWER( SUBSTRING_INDEX( TRIM( REPLACE( SUBSTRING_INDEX(COALESCE(NEW.name, ''), ',', 1), '_', ' ' ) ), ' ', 1 ) ); END Trigger: trigger_updt_time03 Tabelle: kategorie_parts Event: INSERT Timing: AFTER Statement: update ga.last_import_date set stmp = sysdate() where stmp is not null Trigger: trigger_updt_time04 Tabelle: kategorie_parts Event: UPDATE Timing: AFTER Statement: update ga.last_import_date set stmp = sysdate() where stmp is not null Trigger: trigger_updt_time05 Tabelle: kategorie_parts Event: DELETE Timing: AFTER Statement: update ga.last_import_date set stmp = sysdate() where stmp is not null Trigger: trigger_updt_time18 Tabelle: umsaetze Event: INSERT Timing: AFTER Statement: update ga.last_import_date set stmp = sysdate() where stmp is not null Trigger: trigger_updt_time19 Tabelle: umsaetze Event: UPDATE Timing: AFTER Statement: update ga.last_import_date set stmp = sysdate() where stmp is not null Trigger: trigger_updt_time20 Tabelle: umsaetze Event: DELETE Timing: AFTER Statement: update ga.last_import_date set stmp = sysdate() where stmp is not null Trigger: umsaetze_buchtext_preserve_original Tabelle: umsaetze Event: UPDATE Timing: BEFORE Statement: BEGIN -- nur wenn sich buchtext wirklich ändert … IF NEW.buchtext IS NOT NULL AND OLD.buchtext IS NOT NULL AND TRIM(NEW.buchtext) <> TRIM(OLD.buchtext) -- … und noch kein Original abgelegt ist … AND (OLD.abw_buchtext IS NULL OR TRIM(OLD.abw_buchtext) = '') AND (NEW.abw_buchtext IS NULL OR TRIM(NEW.abw_buchtext) = '') THEN -- altes Original sichern SET NEW.abw_buchtext = OLD.buchtext; END IF; END Trigger: umsaetze_match_buchtext_bi Tabelle: umsaetze Event: INSERT Timing: BEFORE Statement: BEGIN SET NEW.match_buchtext = TRIM( CONCAT_WS( ' ', NULLIF(TRIM(NEW.buchtext), ''), NULLIF(TRIM(NEW.abw_buchtext), '') ) ); SET NEW.match_buchtext_norm = TRIM( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( LOWER(CONCAT(' ', COALESCE(NEW.match_buchtext, ''), ' ')), ',', ' ' ), '.', ' ' ), '-', ' ' ), '/', ' ' ), ';', ' ' ), ':', ' ' ), 'straße', 'str' ), 'str.', 'str' ) ); WHILE INSTR(NEW.match_buchtext_norm, ' ') > 0 DO SET NEW.match_buchtext_norm = REPLACE(NEW.match_buchtext_norm, ' ', ' '); END WHILE; END Trigger: umsaetze_match_buchtext_bu Tabelle: umsaetze Event: UPDATE Timing: BEFORE Statement: BEGIN SET NEW.match_buchtext = TRIM( CONCAT_WS( ' ', NULLIF(TRIM(NEW.buchtext), ''), NULLIF(TRIM(NEW.abw_buchtext), '') ) ); SET NEW.match_buchtext_norm = TRIM( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( LOWER(CONCAT(' ', COALESCE(NEW.match_buchtext, ''), ' ')), ',', ' ' ), '.', ' ' ), '-', ' ' ), '/', ' ' ), ';', ' ' ), ':', ' ' ), 'straße', 'str' ), 'str.', 'str' ) ); WHILE INSTR(NEW.match_buchtext_norm, ' ') > 0 DO SET NEW.match_buchtext_norm = REPLACE(NEW.match_buchtext_norm, ' ', ' '); END WHILE; END ==================== FUNCTION STATUS ==================== arrange_buchtext | FUNCTION | root@localhost buchungstext_match | FUNCTION | root@% buchungstext_match_old_v0 | FUNCTION | root@% buchungstext_match_prepared | FUNCTION | root@% buchungstext_match_V1 | FUNCTION | root@% get_enddate | FUNCTION | root@localhost get_startdate | FUNCTION | root@localhost levenshtein | FUNCTION | root@% levenshtein_cleaned_limited | FUNCTION | root@% levenshtein_safe | FUNCTION | root@% levenshtein_utf8 | FUNCTION | root@% ==================== SHOW CREATE FUNCTION buchungstext_match ==================== CREATE DEFINER=`root`@`%` FUNCTION `buchungstext_match`(txt TEXT, part VARCHAR(255)) RETURNS tinyint DETERMINISTIC BEGIN DECLARE t TEXT; DECLARE p TEXT; DECLARE rest TEXT; DECLARE token TEXT; DECLARE pos INT; IF part IS NULL OR TRIM(part) = '' THEN RETURN 0; END IF; -- Text normalisieren SET t = LOWER(CONCAT(' ', txt, ' ')); SET t = REPLACE(t, ',', ' '); SET t = REPLACE(t, '.', ' '); SET t = REPLACE(t, '-', ' '); SET t = REPLACE(t, '/', ' '); SET t = REPLACE(t, ';', ' '); SET t = REPLACE(t, ':', ' '); SET t = REPLACE(t, 'straße', 'str'); SET t = REPLACE(t, 'str.', 'str'); WHILE INSTR(t, ' ') > 0 DO SET t = REPLACE(t, ' ', ' '); END WHILE; SET p = LOWER(TRIM(part)); -- UND-Logik per Komma IF INSTR(p, ',') > 0 THEN SET rest = p; token_loop: LOOP SET pos = LOCATE(',', rest); IF pos > 0 THEN SET token = TRIM(SUBSTRING(rest, 1, pos - 1)); SET rest = SUBSTRING(rest, pos + 1); ELSE SET token = TRIM(rest); SET rest = ''; END IF; IF token <> '' THEN SET token = REPLACE(token, '_', ' '); -- Unterstrich = Phrasen-Trenner IF INSTR(CONCAT(' ', t, ' '), CONCAT(' ', token, ' ')) = 0 THEN RETURN 0; END IF; END IF; IF pos = 0 THEN LEAVE token_loop; END IF; END LOOP; RETURN 1; ELSE -- Einzeltoken / Phrase (Unterstriche zu Leerzeichen) SET p = REPLACE(p, '_', ' '); IF INSTR(CONCAT(' ', t, ' '), CONCAT(' ', p, ' ')) > 0 THEN RETURN 1; END IF; RETURN 0; END IF; END; ==================== SHOW CREATE FUNCTION buchungstext_match_v1 ==================== CREATE DEFINER=`root`@`%` FUNCTION `buchungstext_match_V1`(txt TEXT, part VARCHAR(255)) RETURNS tinyint DETERMINISTIC BEGIN DECLARE t TEXT; DECLARE p TEXT; DECLARE rest TEXT; DECLARE token TEXT; DECLARE pos INT; IF part IS NULL OR part = '' THEN RETURN 0; END IF; -- Text normalisieren SET t = LOWER(CONCAT(' ', txt, ' ')); SET t = REPLACE(t, '-', ' '); SET t = REPLACE(t, '.', ' '); SET t = REPLACE(t, ',', ' '); SET t = REPLACE(t, '/', ' '); SET t = REPLACE(t, 'straße', 'str'); SET t = REPLACE(t, 'str.', 'str'); WHILE INSTR(t, ' ') > 0 DO SET t = REPLACE(t, ' ', ' '); END WHILE; SET p = LOWER(TRIM(part)); -- UND-Logik per Komma IF INSTR(p, ',') > 0 THEN SET rest = p; check_loop: LOOP SET pos = LOCATE(',', rest); IF pos > 0 THEN SET token = TRIM(SUBSTRING(rest, 1, pos - 1)); SET rest = SUBSTRING(rest, pos + 1); ELSE SET token = TRIM(rest); SET rest = ''; END IF; IF token <> '' THEN SET token = REPLACE(token, '_', ' '); -- Wortgrenzen: Leerzeichen um Text und Token IF INSTR(CONCAT(' ', t, ' '), CONCAT(' ', token, ' ')) = 0 THEN RETURN 0; END IF; END IF; IF pos = 0 THEN LEAVE check_loop; END IF; END LOOP; RETURN 1; ELSE -- Phrase (Unterstriche) oder Single-Token SET p = REPLACE(p, '_', ' '); IF INSTR(CONCAT(' ', t, ' '), CONCAT(' ', p, ' ')) > 0 THEN RETURN 1; END IF; RETURN 0; END IF; END; ==================== COLUMNS ==================== kat_part_link | 1 | part_id | int | NO | | | | kat_part_link | 2 | kategorie_id | int | YES | | | | kategorie_parts | 1 | name | varchar(2000) | YES | | | utf8mb4_0900_ai_ci | kategorie_parts | 2 | part_id | int | NO | | auto_increment | | kategorie_parts | 3 | abw_prio | int | YES | | | | kategorie_parts | 4 | match_part | varchar(2000) | YES | | | utf8mb4_0900_ai_ci | kategorie_parts | 5 | match_part_norm | varchar(2000) | YES | | | utf8mb4_0900_ai_ci | kategorie_parts | 6 | match_anchor | varchar(255) | YES | | | utf8mb4_0900_ai_ci | kategorien | 1 | kategorie_id | int | NO | | auto_increment | | kategorien | 2 | name | varchar(700) | YES | | | utf8mb4_0900_ai_ci | kategorien | 3 | abw_kat_kz | int | YES | | | | kategorien | 4 | notiz_vorlage | mediumtext | YES | | | utf8mb4_0900_ai_ci | umsaetze | 1 | pos | int | NO | | | | umsaetze | 2 | betrag | decimal(15,2) | YES | | | | umsaetze | 3 | buchtext | varchar(500) | YES | | | utf8mb4_0900_ai_ci | umsaetze | 4 | valutaStr | varchar(12) | YES | | | utf8mb4_0900_ai_ci | umsaetze | 5 | valuta | date | YES | | | | umsaetze | 6 | unique_id | varchar(100) | NO | | | utf8mb4_0900_ai_ci | umsaetze | 7 | kategorie | varchar(50) | YES | | | utf8mb4_0900_ai_ci | umsaetze | 8 | werte | varchar(1000) | YES | | | utf8mb4_0900_ai_ci | umsaetze | 9 | info | varchar(1000) | YES | | | utf8mb4_0900_ai_ci | umsaetze | 10 | importstmp | timestamp | YES | CURRENT_TIMESTAMP | DEFAULT_GENERATED | | umsaetze | 11 | kategorie_new | varchar(2000) | YES | | | utf8mb4_0900_ai_ci | umsaetze | 12 | abw_valuta | date | YES | | | | umsaetze | 13 | abw_buchtext | varchar(1000) | YES | | | utf8mb4_0900_ai_ci | umsaetze | 14 | hinweis | varchar(1000) | YES | | | utf8mb4_0900_ai_ci | umsaetze | 15 | old_uid | varchar(255) | YES | | | utf8mb4_0900_ai_ci | umsaetze | 16 | valuta_eff | date | YES | | STORED GENERATED | | coalesce(`abw_valuta`,`valuta`) umsaetze | 17 | match_buchtext | text | YES | | | utf8mb4_0900_ai_ci | umsaetze | 18 | match_buchtext_norm | text | YES | | | utf8mb4_0900_ai_ci | umsatz_split | 1 | split_id | int | NO | | auto_increment | | umsatz_split | 2 | parent_pos | int | NO | | | | umsatz_split | 3 | abw_valuta | date | YES | | | | umsatz_split | 4 | betrag | decimal(12,2) | NO | | | | umsatz_split | 5 | kategorie | int | YES | | | | umsatz_split | 6 | buchtext | varchar(700) | YES | | | utf8mb4_0900_ai_ci | umsatz_split | 7 | sort_order | int | NO | 1 | | | umsatz_split | 8 | created_at | timestamp | NO | CURRENT_TIMESTAMP | DEFAULT_GENERATED | | umsatz_split | 9 | abw_buchtext | text | YES | | | utf8mb4_0900_ai_ci | ==================== INDEXES ==================== kat_part_link | idx_part_kat | 0 | 1 | part_id | BTREE kat_part_link | idx_part_kat | 0 | 2 | kategorie_id | BTREE kategorie_parts | idx_match_anchor | 1 | 1 | match_anchor | BTREE kategorie_parts | PRIMARY | 0 | 1 | part_id | BTREE kategorien | name | 0 | 1 | name | BTREE kategorien | PRIMARY | 0 | 1 | kategorie_id | BTREE umsaetze | idx_id | 1 | 1 | pos | BTREE umsaetze | idx_umsaetze_valuta_eff | 1 | 1 | valuta_eff | BTREE umsaetze | pos | 0 | 1 | pos | BTREE umsaetze | unique_id | 0 | 1 | unique_id | BTREE umsatz_split | idx_parent | 1 | 1 | parent_pos | BTREE umsatz_split | PRIMARY | 0 | 1 | split_id | BTREE Datei wurde auch gespeichert unter: /var/www/html/kategorisierung/kat_debug_export_20260524_122131.txt