Mysql Equivalent of php metaphone and soundex - mysql

I am working on an app where user's current playing song title is fetched and we look in the mysql database to see who else is playing a similar song.since the same song might be with many varied titles on everyone's phone , we need a way to effectively find as close results as possible.
The process that we are using right now gets all the songs from the table then do a foreach and compare each entry in the resultset with user's song.
Here is a part of the function we have used:
$all_results = $db->select($sql);//all db entries from the songs table
foreach ( $all_results as $u ) {
$toTest = strtolower( $u['last_song'] );
$toTest = preg_replace('/[^A-Za-z0-9]/', ' ', $toTest);
$score = 0;
$score = $this->calSim( $user_last_song, $toTest, 0 ); //user last song is the current song being played by the user
if ( $score > 1 ) { //if at least there is some match then compare by another method
$score = $this->calMetaphone($user_last_song, $toTest, $score);
}
if ( $score > 5 ) {
//song matches.Push into a final array
}
}
=======================================
here are the 2 custom functions:
public function calMetaphone ( $x, $y, $pts ) {
$x = metaphone( $x );
$y = metaphone( $y );
$pts = $this->calSim( $x, $y, $pts );
return $pts;
}
public function calSim ( $x, $y, $pts ) {
similar_text($x, $y, $sim);
//echo "Similarity is :$sim<br>";
if ( $sim >= 90 ) {
$pts = $pts + 5;
} else if ( $sim >= 80 ) {
$pts = $pts + 4;
}
if ( $sim >= 70 ) {
$pts = $pts + 3;
}
if ( $sim >= 60 ) {
$pts = $pts + 2;
} else {
$pts = $pts + 0;
}
return $pts;
}
But I know this is a real bad way of doing it.If there are large number of entries in database it might take forever to compare them all 1 by 1.
Can anyone tell me the correct method that should be followed here.
Thanks
Karam

I can't take any credit for this but when I needed a similar function I found this (can't remember where though) for a metaphone:-
DROP FUNCTION `func_Double_Metaphone`//
CREATE DEFINER=`aaaa`#`%` FUNCTION `func_Double_Metaphone`(st VARCHAR(55)) RETURNS varchar(128) CHARSET utf8
NO SQL
BEGIN
DECLARE length, first, last, pos, prevpos, is_slavo_germanic SMALLINT;
DECLARE pri, sec VARCHAR(45) DEFAULT '';
DECLARE ch CHAR(1);
SET first = 3;
SET length = CHAR_LENGTH(st);
SET last = first + length -1;
SET st = CONCAT(REPEAT('-', first -1), UCASE(st), REPEAT(' ', 5)); SET is_slavo_germanic = (st LIKE '%W%' OR st LIKE '%K%' OR st LIKE '%CZ%'); SET pos = first; IF SUBSTRING(st, first, 2) IN ('GN', 'KN', 'PN', 'WR', 'PS') THEN
SET pos = pos + 1;
END IF;
IF SUBSTRING(st, first, 1) = 'X' THEN
SET pri = 'S', sec = 'S', pos = pos + 1; END IF;
WHILE pos <= last DO
SET prevpos = pos;
SET ch = SUBSTRING(st, pos, 1); CASE
WHEN ch IN ('A', 'E', 'I', 'O', 'U', 'Y') THEN
IF pos = first THEN SET pri = CONCAT(pri, 'A'), sec = CONCAT(sec, 'A'), pos = pos + 1; ELSE
SET pos = pos + 1;
END IF;
WHEN ch = 'B' THEN
IF SUBSTRING(st, pos+1, 1) = 'B' THEN
SET pri = CONCAT(pri, 'P'), sec = CONCAT(sec, 'P'), pos = pos + 2; ELSE
SET pri = CONCAT(pri, 'P'), sec = CONCAT(sec, 'P'), pos = pos + 1; END IF;
WHEN ch = 'C' THEN
IF (pos > (first + 1) AND SUBSTRING(st, pos-2, 1) NOT IN ('A', 'E', 'I', 'O', 'U', 'Y') AND SUBSTRING(st, pos-1, 3) = 'ACH' AND
(SUBSTRING(st, pos+2, 1) NOT IN ('I', 'E') OR SUBSTRING(st, pos-2, 6) IN ('BACHER', 'MACHER'))) THEN
SET pri = CONCAT(pri, 'K'), sec = CONCAT(sec, 'K'), pos = pos + 2; ELSEIF pos = first AND SUBSTRING(st, first, 6) = 'CAESAR' THEN
SET pri = CONCAT(pri, 'S'), sec = CONCAT(sec, 'S'), pos = pos + 2; ELSEIF SUBSTRING(st, pos, 4) = 'CHIA' THEN SET pri = CONCAT(pri, 'K'), sec = CONCAT(sec, 'K'), pos = pos + 2; ELSEIF SUBSTRING(st, pos, 2) = 'CH' THEN
IF pos > first AND SUBSTRING(st, pos, 4) = 'CHAE' THEN
SET pri = CONCAT(pri, 'K'), sec = CONCAT(sec, 'X'), pos = pos + 2; ELSEIF pos = first AND (SUBSTRING(st, pos+1, 5) IN ('HARAC', 'HARIS') OR
SUBSTRING(st, pos+1, 3) IN ('HOR', 'HYM', 'HIA', 'HEM')) AND SUBSTRING(st, first, 5) != 'CHORE' THEN
SET pri = CONCAT(pri, 'K'), sec = CONCAT(sec, 'K'), pos = pos + 2; ELSEIF SUBSTRING(st, first, 4) IN ('VAN ', 'VON ') OR SUBSTRING(st, first, 3) = 'SCH'
OR SUBSTRING(st, pos-2, 6) IN ('ORCHES', 'ARCHIT', 'ORCHID')
OR SUBSTRING(st, pos+2, 1) IN ('T', 'S')
OR ((SUBSTRING(st, pos-1, 1) IN ('A', 'O', 'U', 'E') OR pos = first)
AND SUBSTRING(st, pos+2, 1) IN ('L', 'R', 'N', 'M', 'B', 'H', 'F', 'V', 'W', ' ')) THEN
SET pri = CONCAT(pri, 'K'), sec = CONCAT(sec, 'K'), pos = pos + 2; ELSE
IF pos > first THEN
IF SUBSTRING(st, first, 2) = 'MC' THEN
SET pri = CONCAT(pri, 'K'), sec = CONCAT(sec, 'K'), pos = pos + 2; ELSE
SET pri = CONCAT(pri, 'X'), sec = CONCAT(sec, 'K'), pos = pos + 2; END IF;
ELSE
SET pri = CONCAT(pri, 'X'), sec = CONCAT(sec, 'X'), pos = pos + 2; END IF;
END IF;
ELSEIF SUBSTRING(st, pos, 2) = 'CZ' AND SUBSTRING(st, pos-2, 4) != 'WICZ' THEN
SET pri = CONCAT(pri, 'S'), sec = CONCAT(sec, 'X'), pos = pos + 2; ELSEIF SUBSTRING(st, pos+1, 3) = 'CIA' THEN
SET pri = CONCAT(pri, 'X'), sec = CONCAT(sec, 'X'), pos = pos + 3; ELSEIF SUBSTRING(st, pos, 2) = 'CC' AND NOT (pos = (first +1) AND SUBSTRING(st, first, 1) = 'M') THEN
IF SUBSTRING(st, pos+2, 1) IN ('I', 'E', 'H') AND SUBSTRING(st, pos+2, 2) != 'HU' THEN
IF (pos = first +1 AND SUBSTRING(st, first) = 'A') OR
SUBSTRING(st, pos-1, 5) IN ('UCCEE', 'UCCES') THEN
SET pri = CONCAT(pri, 'KS'), sec = CONCAT(sec, 'KS'), pos = pos + 3; ELSE
SET pri = CONCAT(pri, 'X'), sec = CONCAT(sec, 'X'), pos = pos + 3; END IF;
ELSE
SET pri = CONCAT(pri, 'K'), sec = CONCAT(sec, 'K'), pos = pos + 2; END IF;
ELSEIF SUBSTRING(st, pos, 2) IN ('CK', 'CG', 'CQ') THEN
SET pri = CONCAT(pri, 'K'), sec = CONCAT(sec, 'K'), pos = pos + 2; ELSEIF SUBSTRING(st, pos, 2) IN ('CI', 'CE', 'CY') THEN
IF SUBSTRING(st, pos, 3) IN ('CIO', 'CIE', 'CIA') THEN
SET pri = CONCAT(pri, 'S'), sec = CONCAT(sec, 'X'), pos = pos + 2; ELSE
SET pri = CONCAT(pri, 'S'), sec = CONCAT(sec, 'S'), pos = pos + 2; END IF;
ELSE
IF SUBSTRING(st, pos+1, 2) IN (' C', ' Q', ' G') THEN
SET pri = CONCAT(pri, 'K'), sec = CONCAT(sec, 'K'), pos = pos + 3; ELSE
IF SUBSTRING(st, pos+1, 1) IN ('C', 'K', 'Q') AND SUBSTRING(st, pos+1, 2) NOT IN ('CE', 'CI') THEN
SET pri = CONCAT(pri, 'K'), sec = CONCAT(sec, 'K'), pos = pos + 2; ELSE SET pri = CONCAT(pri, 'K'), sec = CONCAT(sec, 'K'), pos = pos + 1; END IF;
END IF;
END IF;
WHEN ch = 'D' THEN
IF SUBSTRING(st, pos, 2) = 'DG' THEN
IF SUBSTRING(st, pos+2, 1) IN ('I', 'E', 'Y') THEN SET pri = CONCAT(pri, 'J'), sec = CONCAT(sec, 'J'), pos = pos + 3; ELSE
SET pri = CONCAT(pri, 'TK'), sec = CONCAT(sec, 'TK'), pos = pos + 2; END IF;
ELSEIF SUBSTRING(st, pos, 2) IN ('DT', 'DD') THEN
SET pri = CONCAT(pri, 'T'), sec = CONCAT(sec, 'T'), pos = pos + 2; ELSE
SET pri = CONCAT(pri, 'T'), sec = CONCAT(sec, 'T'), pos = pos + 1; END IF;
WHEN ch = 'F' THEN
IF SUBSTRING(st, pos+1, 1) = 'F' THEN
SET pri = CONCAT(pri, 'F'), sec = CONCAT(sec, 'F'), pos = pos + 2; ELSE
SET pri = CONCAT(pri, 'F'), sec = CONCAT(sec, 'F'), pos = pos + 1; END IF;
WHEN ch = 'G' THEN
IF SUBSTRING(st, pos+1, 1) = 'H' THEN
IF (pos > first AND SUBSTRING(st, pos-1, 1) NOT IN ('A', 'E', 'I', 'O', 'U', 'Y'))
OR ( pos = first AND SUBSTRING(st, pos+2, 1) != 'I') THEN
SET pri = CONCAT(pri, 'K'), sec = CONCAT(sec, 'K'), pos = pos + 2; ELSEIF pos = first AND SUBSTRING(st, pos+2, 1) = 'I' THEN
SET pri = CONCAT(pri, 'J'), sec = CONCAT(sec, 'J'), pos = pos + 2; ELSEIF (pos > (first + 1) AND SUBSTRING(st, pos-2, 1) IN ('B', 'H', 'D') )
OR (pos > (first + 2) AND SUBSTRING(st, pos-3, 1) IN ('B', 'H', 'D') )
OR (pos > (first + 3) AND SUBSTRING(st, pos-4, 1) IN ('B', 'H') ) THEN
SET pos = pos + 2; ELSE
IF pos > (first + 2) AND SUBSTRING(st, pos-1, 1) = 'U'
AND SUBSTRING(st, pos-3, 1) IN ('C', 'G', 'L', 'R', 'T') THEN
SET pri = CONCAT(pri, 'F'), sec = CONCAT(sec, 'F'), pos = pos + 2; ELSEIF pos > first AND SUBSTRING(st, pos-1, 1) != 'I' THEN
SET pri = CONCAT(pri, 'K'), sec = CONCAT(sec, 'K'), pos = pos + 2; ELSE
SET pos = pos + 1;
END IF;
END IF;
ELSEIF SUBSTRING(st, pos+1, 1) = 'N' THEN
IF pos = (first +1) AND SUBSTRING(st, first, 1) IN ('A', 'E', 'I', 'O', 'U', 'Y') AND NOT is_slavo_germanic THEN
SET pri = CONCAT(pri, 'KN'), sec = CONCAT(sec, 'N'), pos = pos + 2; ELSE
IF SUBSTRING(st, pos+2, 2) != 'EY' AND SUBSTRING(st, pos+1, 1) != 'Y'
AND NOT is_slavo_germanic THEN
SET pri = CONCAT(pri, 'N'), sec = CONCAT(sec, 'KN'), pos = pos + 2; ELSE
SET pri = CONCAT(pri, 'KN'), sec = CONCAT(sec, 'KN'), pos = pos + 2; END IF;
END IF;
ELSEIF SUBSTRING(st, pos+1, 2) = 'LI' AND NOT is_slavo_germanic THEN
SET pri = CONCAT(pri, 'KL'), sec = CONCAT(sec, 'L'), pos = pos + 2; ELSEIF pos = first AND (SUBSTRING(st, pos+1, 1) = 'Y'
OR SUBSTRING(st, pos+1, 2) IN ('ES', 'EP', 'EB', 'EL', 'EY', 'IB', 'IL', 'IN', 'IE', 'EI', 'ER')) THEN
SET pri = CONCAT(pri, 'K'), sec = CONCAT(sec, 'J'), pos = pos + 2; ELSEIF (SUBSTRING(st, pos+1, 2) = 'ER' OR SUBSTRING(st, pos+1, 1) = 'Y')
AND SUBSTRING(st, first, 6) NOT IN ('DANGER', 'RANGER', 'MANGER')
AND SUBSTRING(st, pos-1, 1) not IN ('E', 'I') AND SUBSTRING(st, pos-1, 3) NOT IN ('RGY', 'OGY') THEN
SET pri = CONCAT(pri, 'K'), sec = CONCAT(sec, 'J'), pos = pos + 2; ELSEIF SUBSTRING(st, pos+1, 1) IN ('E', 'I', 'Y') OR SUBSTRING(st, pos-1, 4) IN ('AGGI', 'OGGI') THEN
IF SUBSTRING(st, first, 4) IN ('VON ', 'VAN ') OR SUBSTRING(st, first, 3) = 'SCH'
OR SUBSTRING(st, pos+1, 2) = 'ET' THEN
SET pri = CONCAT(pri, 'K'), sec = CONCAT(sec, 'K'), pos = pos + 2; ELSE
IF SUBSTRING(st, pos+1, 4) = 'IER ' THEN
SET pri = CONCAT(pri, 'J'), sec = CONCAT(sec, 'J'), pos = pos + 2; ELSE
SET pri = CONCAT(pri, 'J'), sec = CONCAT(sec, 'K'), pos = pos + 2; END IF;
END IF;
ELSEIF SUBSTRING(st, pos+1, 1) = 'G' THEN
SET pri = CONCAT(pri, 'K'), sec = CONCAT(sec, 'K'), pos = pos + 2; ELSE
SET pri = CONCAT(pri, 'K'), sec = CONCAT(sec, 'K'), pos = pos + 1; END IF;
WHEN ch = 'H' THEN
IF (pos = first OR SUBSTRING(st, pos-1, 1) IN ('A', 'E', 'I', 'O', 'U', 'Y'))
AND SUBSTRING(st, pos+1, 1) IN ('A', 'E', 'I', 'O', 'U', 'Y') THEN
SET pri = CONCAT(pri, 'H'), sec = CONCAT(sec, 'H'), pos = pos + 2; ELSE SET pos = pos + 1; END IF;
WHEN ch = 'J' THEN
IF SUBSTRING(st, pos, 4) = 'JOSE' OR SUBSTRING(st, first, 4) = 'SAN ' THEN
IF (pos = first AND SUBSTRING(st, pos+4, 1) = ' ') OR SUBSTRING(st, first, 4) = 'SAN ' THEN
SET pri = CONCAT(pri, 'H'), sec = CONCAT(sec, 'H'); ELSE
SET pri = CONCAT(pri, 'J'), sec = CONCAT(sec, 'H'); END IF;
ELSEIF pos = first AND SUBSTRING(st, pos, 4) != 'JOSE' THEN
SET pri = CONCAT(pri, 'J'), sec = CONCAT(sec, 'A'); ELSE
IF SUBSTRING(st, pos-1, 1) IN ('A', 'E', 'I', 'O', 'U', 'Y') AND NOT is_slavo_germanic
AND SUBSTRING(st, pos+1, 1) IN ('A', 'O') THEN
SET pri = CONCAT(pri, 'J'), sec = CONCAT(sec, 'H'); ELSE
IF pos = last THEN
SET pri = CONCAT(pri, 'J'); ELSE
IF SUBSTRING(st, pos+1, 1) not IN ('L', 'T', 'K', 'S', 'N', 'M', 'B', 'Z')
AND SUBSTRING(st, pos-1, 1) not IN ('S', 'K', 'L') THEN
SET pri = CONCAT(pri, 'J'), sec = CONCAT(sec, 'J'); END IF;
END IF;
END IF;
END IF;
IF SUBSTRING(st, pos+1, 1) = 'J' THEN
SET pos = pos + 2;
ELSE
SET pos = pos + 1;
END IF;
WHEN ch = 'K' THEN
IF SUBSTRING(st, pos+1, 1) = 'K' THEN
SET pri = CONCAT(pri, 'K'), sec = CONCAT(sec, 'K'), pos = pos + 2; ELSE
SET pri = CONCAT(pri, 'K'), sec = CONCAT(sec, 'K'), pos = pos + 1; END IF;
WHEN ch = 'L' THEN
IF SUBSTRING(st, pos+1, 1) = 'L' THEN
IF (pos = (last - 2) AND SUBSTRING(st, pos-1, 4) IN ('ILLO', 'ILLA', 'ALLE'))
OR ((SUBSTRING(st, last-1, 2) IN ('AS', 'OS') OR SUBSTRING(st, last) IN ('A', 'O'))
AND SUBSTRING(st, pos-1, 4) = 'ALLE') THEN
SET pri = CONCAT(pri, 'L'), pos = pos + 2; ELSE
SET pri = CONCAT(pri, 'L'), sec = CONCAT(sec, 'L'), pos = pos + 2; END IF;
ELSE
SET pri = CONCAT(pri, 'L'), sec = CONCAT(sec, 'L'), pos = pos + 1; END IF;
WHEN ch = 'M' THEN
IF SUBSTRING(st, pos-1, 3) = 'UMB'
AND (pos + 1 = last OR SUBSTRING(st, pos+2, 2) = 'ER')
OR SUBSTRING(st, pos+1, 1) = 'M' THEN
SET pri = CONCAT(pri, 'M'), sec = CONCAT(sec, 'M'), pos = pos + 2; ELSE
SET pri = CONCAT(pri, 'M'), sec = CONCAT(sec, 'M'), pos = pos + 1; END IF;
WHEN ch = 'N' THEN
IF SUBSTRING(st, pos+1, 1) = 'N' THEN
SET pri = CONCAT(pri, 'N'), sec = CONCAT(sec, 'N'), pos = pos + 2; ELSE
SET pri = CONCAT(pri, 'N'), sec = CONCAT(sec, 'N'), pos = pos + 1; END IF;
WHEN ch = 'P' THEN
IF SUBSTRING(st, pos+1, 1) = 'H' THEN
SET pri = CONCAT(pri, 'F'), sec = CONCAT(sec, 'F'), pos = pos + 2; ELSEIF SUBSTRING(st, pos+1, 1) IN ('P', 'B') THEN SET pri = CONCAT(pri, 'P'), sec = CONCAT(sec, 'P'), pos = pos + 2; ELSE
SET pri = CONCAT(pri, 'P'), sec = CONCAT(sec, 'P'), pos = pos + 1; END IF;
WHEN ch = 'Q' THEN
IF SUBSTRING(st, pos+1, 1) = 'Q' THEN
SET pri = CONCAT(pri, 'K'), sec = CONCAT(sec, 'K'), pos = pos + 2; ELSE
SET pri = CONCAT(pri, 'K'), sec = CONCAT(sec, 'K'), pos = pos + 1; END IF;
WHEN ch = 'R' THEN
IF pos = last AND not is_slavo_germanic
AND SUBSTRING(st, pos-2, 2) = 'IE' AND SUBSTRING(st, pos-4, 2) NOT IN ('ME', 'MA') THEN
SET sec = CONCAT(sec, 'R'); ELSE
SET pri = CONCAT(pri, 'R'), sec = CONCAT(sec, 'R'); END IF;
IF SUBSTRING(st, pos+1, 1) = 'R' THEN
SET pos = pos + 2;
ELSE
SET pos = pos + 1;
END IF;
WHEN ch = 'S' THEN
IF SUBSTRING(st, pos-1, 3) IN ('ISL', 'YSL') THEN
SET pos = pos + 1;
ELSEIF pos = first AND SUBSTRING(st, first, 5) = 'SUGAR' THEN
SET pri = CONCAT(pri, 'X'), sec = CONCAT(sec, 'S'), pos = pos + 1; ELSEIF SUBSTRING(st, pos, 2) = 'SH' THEN
IF SUBSTRING(st, pos+1, 4) IN ('HEIM', 'HOEK', 'HOLM', 'HOLZ') THEN
SET pri = CONCAT(pri, 'S'), sec = CONCAT(sec, 'S'), pos = pos + 2; ELSE
SET pri = CONCAT(pri, 'X'), sec = CONCAT(sec, 'X'), pos = pos + 2; END IF;
ELSEIF SUBSTRING(st, pos, 3) IN ('SIO', 'SIA') OR SUBSTRING(st, pos, 4) = 'SIAN' THEN
IF NOT is_slavo_germanic THEN
SET pri = CONCAT(pri, 'S'), sec = CONCAT(sec, 'X'), pos = pos + 3; ELSE
SET pri = CONCAT(pri, 'S'), sec = CONCAT(sec, 'S'), pos = pos + 3; END IF;
ELSEIF (pos = first AND SUBSTRING(st, pos+1, 1) IN ('M', 'N', 'L', 'W')) OR SUBSTRING(st, pos+1, 1) = 'Z' THEN
SET pri = CONCAT(pri, 'S'), sec = CONCAT(sec, 'X'); IF SUBSTRING(st, pos+1, 1) = 'Z' THEN
SET pos = pos + 2;
ELSE
SET pos = pos + 1;
END IF;
ELSEIF SUBSTRING(st, pos, 2) = 'SC' THEN
IF SUBSTRING(st, pos+2, 1) = 'H' THEN
IF SUBSTRING(st, pos+3, 2) IN ('OO', 'ER', 'EN', 'UY', 'ED', 'EM') THEN
IF SUBSTRING(st, pos+3, 2) IN ('ER', 'EN') THEN
SET pri = CONCAT(pri, 'X'), sec = CONCAT(sec, 'SK'), pos = pos + 3; ELSE
SET pri = CONCAT(pri, 'SK'), sec = CONCAT(sec, 'SK'), pos = pos + 3; END IF;
ELSE
IF pos = first AND SUBSTRING(st, first+3, 1) not IN ('A', 'E', 'I', 'O', 'U', 'Y') AND SUBSTRING(st, first+3, 1) != 'W' THEN
SET pri = CONCAT(pri, 'X'), sec = CONCAT(sec, 'S'), pos = pos + 3; ELSE
SET pri = CONCAT(pri, 'X'), sec = CONCAT(sec, 'X'), pos = pos + 3; END IF;
END IF;
ELSEIF SUBSTRING(st, pos+2, 1) IN ('I', 'E', 'Y') THEN
SET pri = CONCAT(pri, 'S'), sec = CONCAT(sec, 'S'), pos = pos + 3; ELSE
SET pri = CONCAT(pri, 'SK'), sec = CONCAT(sec, 'SK'), pos = pos + 3; END IF;
ELSEIF pos = last AND SUBSTRING(st, pos-2, 2) IN ('AI', 'OI') THEN
SET sec = CONCAT(sec, 'S'), pos = pos + 1; ELSE
SET pri = CONCAT(pri, 'S'), sec = CONCAT(sec, 'S'); IF SUBSTRING(st, pos+1, 1) IN ('S', 'Z') THEN
SET pos = pos + 2;
ELSE
SET pos = pos + 1;
END IF;
END IF;
WHEN ch = 'T' THEN
IF SUBSTRING(st, pos, 4) = 'TION' THEN
SET pri = CONCAT(pri, 'X'), sec = CONCAT(sec, 'X'), pos = pos + 3; ELSEIF SUBSTRING(st, pos, 3) IN ('TIA', 'TCH') THEN
SET pri = CONCAT(pri, 'X'), sec = CONCAT(sec, 'X'), pos = pos + 3; ELSEIF SUBSTRING(st, pos, 2) = 'TH' OR SUBSTRING(st, pos, 3) = 'TTH' THEN
IF SUBSTRING(st, pos+2, 2) IN ('OM', 'AM') OR SUBSTRING(st, first, 4) IN ('VON ', 'VAN ')
OR SUBSTRING(st, first, 3) = 'SCH' THEN
SET pri = CONCAT(pri, 'T'), sec = CONCAT(sec, 'T'), pos = pos + 2; ELSE
SET pri = CONCAT(pri, '0'), sec = CONCAT(sec, 'T'), pos = pos + 2; END IF;
ELSEIF SUBSTRING(st, pos+1, 1) IN ('T', 'D') THEN
SET pri = CONCAT(pri, 'T'), sec = CONCAT(sec, 'T'), pos = pos + 2; ELSE
SET pri = CONCAT(pri, 'T'), sec = CONCAT(sec, 'T'), pos = pos + 1; END IF;
WHEN ch = 'V' THEN
IF SUBSTRING(st, pos+1, 1) = 'V' THEN
SET pri = CONCAT(pri, 'F'), sec = CONCAT(sec, 'F'), pos = pos + 2; ELSE
SET pri = CONCAT(pri, 'F'), sec = CONCAT(sec, 'F'), pos = pos + 1; END IF;
WHEN ch = 'W' THEN
IF SUBSTRING(st, pos, 2) = 'WR' THEN
SET pri = CONCAT(pri, 'R'), sec = CONCAT(sec, 'R'), pos = pos + 2; ELSEIF pos = first AND (SUBSTRING(st, pos+1, 1) IN ('A', 'E', 'I', 'O', 'U', 'Y')
OR SUBSTRING(st, pos, 2) = 'WH') THEN
IF SUBSTRING(st, pos+1, 1) IN ('A', 'E', 'I', 'O', 'U', 'Y') THEN
SET pri = CONCAT(pri, 'A'), sec = CONCAT(sec, 'F'), pos = pos + 1; ELSE
SET pri = CONCAT(pri, 'A'), sec = CONCAT(sec, 'A'), pos = pos + 1; END IF;
ELSEIF (pos = last AND SUBSTRING(st, pos-1, 1) IN ('A', 'E', 'I', 'O', 'U', 'Y'))
OR SUBSTRING(st, pos-1, 5) IN ('EWSKI', 'EWSKY', 'OWSKI', 'OWSKY')
OR SUBSTRING(st, first, 3) = 'SCH' THEN
SET sec = CONCAT(sec, 'F'), pos = pos + 1; ELSEIF SUBSTRING(st, pos, 4) IN ('WICZ', 'WITZ') THEN
SET pri = CONCAT(pri, 'TS'), sec = CONCAT(sec, 'FX'), pos = pos + 4; ELSE SET pos = pos + 1;
END IF;
WHEN ch = 'X' THEN
IF not(pos = last AND (SUBSTRING(st, pos-3, 3) IN ('IAU', 'EAU')
OR SUBSTRING(st, pos-2, 2) IN ('AU', 'OU'))) THEN
SET pri = CONCAT(pri, 'KS'), sec = CONCAT(sec, 'KS'); END IF;
IF SUBSTRING(st, pos+1, 1) IN ('C', 'X') THEN
SET pos = pos + 2;
ELSE
SET pos = pos + 1;
END IF;
WHEN ch = 'Z' THEN
IF SUBSTRING(st, pos+1, 1) = 'H' THEN
SET pri = CONCAT(pri, 'J'), sec = CONCAT(sec, 'J'), pos = pos + 1; ELSEIF SUBSTRING(st, pos+1, 3) IN ('ZO', 'ZI', 'ZA')
OR (is_slavo_germanic AND pos > first AND SUBSTRING(st, pos-1, 1) != 'T') THEN
SET pri = CONCAT(pri, 'S'), sec = CONCAT(sec, 'TS'); ELSE
SET pri = CONCAT(pri, 'S'), sec = CONCAT(sec, 'S'); END IF;
IF SUBSTRING(st, pos+1, 1) = 'Z' THEN
SET pos = pos + 2;
ELSE
SET pos = pos + 1;
END IF;
ELSE
SET pos = pos + 1; END CASE;
IF pos = prevpos THEN
SET pos = pos +1;
SET pri = CONCAT(pri,'<didnt incr>'); END IF;
END WHILE;
IF pri != sec THEN
SET pri = CONCAT(pri, ';', sec);
END IF;
RETURN (pri);
END
I also needed a levenshtein function and managed to sort out one of those, but performance was such (when comparing values from many rows) that it was far faster to read the rows and use the php built in levenshtein function.

Related

MySQL - Matching Two Tables

I have two tables, first called list_city contain list of city in Europe, example:
=========================
= ID = CITY = COUNTRY =
=========================
= 1 = LONDON = UK =
= 2 = PARIS = France =
= 3 = ROME = Italy =
=========================
and the second one is data_customer, contain id_cust and city (but in mess typing)
====================
= ID_CUST = CITY =
====================
= 012AGH = paris =
= 2X4BV = London =
= M3RT45 = romE =
= 1F546 = Lndon =
= 345GC = PArs =
= 54A78 = roma =
====================
How I can matching in the city in the second table with the city in the first table in mysql so the output will be:
====================
= ID_CUST = CITY =
====================
= 012AGH = PARIS =
= 2X4BV = LONDON =
= M3RT45 = ROME =
= 1F546 = LONDON =
= 345GC = PARIS =
= 54A78 = ROME =
====================
I tried
SELECT c1.ID_CUST, c2.CITY FROM data_customer c1 INNER JOIN list_city c2
ON c1.CITY LIKE concat('%',c2.CITY,'%');
But, It's seem not work as Iexpected. It's possible do it only in mysql? If not can anyone give me another solution? Thank you very much I really appreciate your time to help me.
Use Levenshtein distance.
SELECT DISTINCT
data_customer.id_cust,
FIRST_VALUE(list_city.city) OVER ( PARTITION BY data_customer.id_cust
ORDER BY levenshtein(UPPER(list_city.city), UPPER(data_customer.city))) city
FROM list_city
CROSS JOIN data_customer;
Of course you must create user-defined function:
CREATE FUNCTION levenshtein( s1 VARCHAR(255), s2 VARCHAR(255) )
RETURNS INT
DETERMINISTIC
BEGIN
DECLARE s1_len, s2_len, i, j, c, c_temp, cost INT;
DECLARE s1_char CHAR;
DECLARE cv0, cv1 VARBINARY(256);
SET s1_len = CHAR_LENGTH(s1),
s2_len = CHAR_LENGTH(s2),
cv1 = 0x00,
j = 1,
i = 1,
c = 0;
IF s1 = s2 THEN
RETURN 0;
ELSEIF s1_len = 0 THEN
RETURN s2_len;
ELSEIF s2_len = 0 THEN
RETURN s1_len;
ELSE
WHILE j <= s2_len DO
SET cv1 = CONCAT(cv1, UNHEX(HEX(j))),
j = j + 1;
END WHILE;
WHILE i <= s1_len DO
SET s1_char = SUBSTRING(s1, i, 1),
c = i,
cv0 = UNHEX(HEX(i)),
j = 1;
WHILE j <= s2_len DO
SET c = c + 1;
IF s1_char = SUBSTRING(s2, j, 1) THEN
SET cost = 0;
ELSE
SET cost = 1;
END IF;
SET c_temp = CONV(HEX(SUBSTRING(cv1, j, 1)), 16, 10) + cost;
IF c > c_temp THEN
SET c = c_temp;
END IF;
SET c_temp = CONV(HEX(SUBSTRING(cv1, j+1, 1)), 16, 10) + 1;
IF c > c_temp THEN
SET c = c_temp;
END IF;
SET cv0 = CONCAT(cv0, UNHEX(HEX(c))),
j = j + 1;
END WHILE;
SET cv1 = cv0,
i = i + 1;
END WHILE;
END IF;
RETURN c;
END;
fiddle

error code 1048 column 'value' cannot be null

i have SP for update the data into new data with this query, so basically every id have own value for own rule_id, and this SP is to update the data with the new one from the SP
CREATE DEFINER=`root`#`localhost` PROCEDURE `update_discount_campaign_advanced2`(IN DiscountCampaignId INT(10),
IN rule_percentage VARCHAR(255),
IN rule_quota_daily_max VARCHAR(255),
IN rule_discount_daily VARCHAR(255),
IN rule_discount_weekly VARCHAR (255),
IN rule_discount_monthly VARCHAR(255),
IN rule_spesific_payment_method VARCHAR(255),
IN rule_spesific_cc_operator VARCHAR(255),
IN allow_other_product VARCHAR(255)
)
proc:
BEGIN
DECLARE is_discount_campaign_id INT(10);
DECLARE is_rule_percentage VARCHAR(255);
DECLARE is_rule_quota_daily_max VARCHAR(255);
DECLARE is_rule_discount_daily VARCHAR(255);
DECLARE is_rule_discount_weekly VARCHAR(255);
DECLARE is_rule_discount_monthly VARCHAR(255);
DECLARE is_rule_spesific_payment_method VARCHAR(255);
DECLARE is_rule_spesific_cc_operator VARCHAR(255);
DECLARE is_allow_other_product VARCHAR(255);
DECLARE param_1_message TEXT;
SET #is_discount_campaign_id = DiscountCampaignId;
SET #is_rule_percentage = rule_percentage;
SET #is_rule_quota_daily_max = rule_quota_daily_max;
SET #is_rule_discount_daily = rule_discount_daily;
SET #is_rule_discount_weekly = rule_discount_weekly;
SET #is_rule_discount_monthly = rule_discount_monthly;
SET #is_rule_spesific_payment_method = rule_spesific_payment_method;
SET #is_rule_spesific_cc_operator = rule_spesific_cc_operator;
SET #is_allow_other_product = allow_other_product;
SELECT CONVERT( CONCAT('Maaf, ID discount_campaign tidak bisa \'0\'') USING UTF8) INTO param_1_message;
IF (DiscountCampaignId = 0) THEN
SELECT param_1_message AS message;
LEAVE proc;
END IF;
IF (DiscountCampaignId != 0) THEN
INSERT INTO discount_campaign_advanced (id,discount_campaign_id,
discount_advanced_rules_id, value, createdAt, status, updatedAt)
select *, CASE WHEN
unitData.id is NULL THEN NULL ELSE NOW() END as updatedAt from (SELECT dca.id , DiscountCampaignId, dar.id as dar_id1, CASE WHEN dar.id = 1
THEN #is_rule_percentage WHEN dar.id = 2 THEN #is_rule_quota_daily_max
WHEN dar.id = 3 THEN #is_rule_discount_daily WHEN dar.id = 4
THEN #is_rule_discount_weekly WHEN dar.id = 5 THEN #is_rule_discount_monthly
WHEN dar.id = 6 THEN #is_rule_spesific_payment_method WHEN dar.id = 7
THEN #is_rule_spesific_cc_operator END, coalesce(dca.createdAt, NOW()), CASE when (dar.id = 1
and #is_rule_percentage != '0') THEN 1 WHEN (dar.id = 2 and
#is_rule_quota_daily_max != '0') THEN 1 WHEN
(dar.id = 3 and #is_rule_discount_daily != '0') THEN 1 WHEN (dar.id = 4 and
#is_rule_discount_weekly != '0') THEN 1
WHEN (dar.id = 5 AND #is_rule_discount_monthly != '0') THEN 1 WHEN (dar.id = 6
AND #is_rule_spesific_payment_method != '0')
THEN 1 WHEN (dar.id = 7 AND #is_rule_spesific_cc_operator != '0') THEN 1 ELSE 0 END as bb
FROM
discount_advanced_rules dar
LEFT JOIN
discount_campaign_advanced dca ON dca.discount_advanced_rules_id = dar.id
and dca.discount_campaign_id = DiscountCampaignId) as unitData
WHERE unitData.bb = 1
UNION
SELECT dca.id, DiscountCampaignId, dca.discount_advanced_rules_id, CASE WHEN dca.discount_advanced_rules_id = 1
THEN #is_rule_percentage WHEN dca.discount_advanced_rules_id = 2 THEN #is_rule_quota_daily_max
WHEN dca.discount_advanced_rules_id = 3 THEN #is_rule_discount_daily WHEN dca.discount_advanced_rules_id = 4
THEN #is_rule_discount_weekly WHEN dca.discount_advanced_rules_id = 5 THEN #is_rule_discount_monthly
WHEN dca.discount_advanced_rules_id = 6 THEN #is_rule_spesific_payment_method WHEN dca.discount_advanced_rules_id = 7
THEN #is_rule_spesific_cc_operator END, coalesce(dca.createdAt, NOW()), CASE when (dca.discount_advanced_rules_id = 1
and #is_rule_percentage != '0') THEN 1 WHEN (dca.discount_advanced_rules_id = 2 and
#is_rule_quota_daily_max != '0') THEN 1 WHEN
(dca.discount_advanced_rules_id = 3 and #is_rule_discount_daily != '0')
THEN 1 WHEN (dca.discount_advanced_rules_id = 4 and
#is_rule_discount_weekly != '0') THEN 1
WHEN (dca.discount_advanced_rules_id = 5
AND #is_rule_discount_monthly != '0') THEN 1 WHEN (dca.discount_advanced_rules_id = 6
AND #is_rule_spesific_payment_method != '0')
THEN 1 WHEN (dca.discount_advanced_rules_id = 7 AND #is_rule_spesific_cc_operator != '0') THEN 1 ELSE 0 END as bb,
NOW()
FROM discount_campaign_advanced dca
WHERE dca.discount_campaign_id = DiscountCampaignId
on duplicate key update id = values(id), discount_campaign_id = values(discount_campaign_id),
discount_advanced_rules_id = values(discount_advanced_rules_id), value = values(value),
createdAt = values(createdAt), status = values(status), updatedAt = values(updatedAt);
END IF;
IF (allow_other_product != 0) THEN
INSERT INTO discount_campaign_advanced (id,discount_campaign_id,
discount_advanced_rules_id, value, createdAt, status, updatedAt)
select *, CASE WHEN
unitData.id is NULL THEN NULL ELSE NOW() END as updatedAt from (SELECT dca.id , DiscountCampaignId, dar.id as dar_id1, CASE WHEN dar.id = 8
THEN #is_allow_other_product END, coalesce(dca.createdAt, NOW()), CASE when (dar.id = 8
and #is_allow_other_product != '0') THEN 1 ELSE 0 END as bb
FROM
discount_advanced_rules dar
LEFT JOIN
discount_campaign_advanced dca ON dca.discount_advanced_rules_id = dar.id
and dca.discount_campaign_id = DiscountCampaignId) as unitData
WHERE unitData.bb = 1
UNION
SELECT dca.id, DiscountCampaignId, dca.discount_advanced_rules_id, CASE WHEN dca.discount_advanced_rules_id = 8 THEN #is_allow_other_product END, coalesce(dca.createdAt, NOW()), CASE when (dca.discount_advanced_rules_id = 8
and #is_allow_other_product != '0') THEN 1 ELSE 0 END as bb,
NOW()
FROM discount_campaign_advanced dca
WHERE dca.discount_campaign_id = DiscountCampaignId
on duplicate key update id = values(id), discount_campaign_id = values(discount_campaign_id),
discount_advanced_rules_id = values(discount_advanced_rules_id), value = values(value),
createdAt = values(createdAt), status = values(status), updatedAt = values(updatedAt);
END IF;
END
but idk why when i call this SP call brambang_uom.update_discount_campaign_advanced2(2757, '5', '5', '1', '1', '1', '1', '1', '9');
it returns Error Code: 1048. Column 'value' cannot be null`, where my wrong at?

rot13 function on MYSQL

I've searched all the internet looking for this.
Anyone has a rot13 function on MYSQL?
Edit: It has to be a function in SQL.
Made at brute force:
CREATE FUNCTION rot13(stringIn VARCHAR(500)) RETURNS VARCHAR(500)
BEGIN
DECLARE v1 INT DEFAULT 1;
DECLARE stringOut VARCHAR(200) DEFAULT '';
DECLARE str VARCHAR(1) DEFAULT '';
WHILE v1 <= LENGTH(stringIn) DO
SET str = SUBSTR(stringIn,v1,1);
CASE BINARY str
WHEN 'A' THEN SET stringOut = CONCAT(stringOut , 'N');
WHEN 'a' THEN SET stringOut = CONCAT(stringOut , 'n');
WHEN 'B' THEN SET stringOut = CONCAT(stringOut , 'O');
WHEN 'b' THEN SET stringOut = CONCAT(stringOut , 'o');
WHEN 'C' THEN SET stringOut = CONCAT(stringOut , 'P');
WHEN 'c' THEN SET stringOut = CONCAT(stringOut , 'p');
WHEN 'D' THEN SET stringOut = CONCAT(stringOut , 'Q');
WHEN 'd' THEN SET stringOut = CONCAT(stringOut , 'q');
WHEN 'E' THEN SET stringOut = CONCAT(stringOut , 'R');
WHEN 'e' THEN SET stringOut = CONCAT(stringOut , 'r');
WHEN 'F' THEN SET stringOut = CONCAT(stringOut , 'S');
WHEN 'f' THEN SET stringOut = CONCAT(stringOut , 's');
WHEN 'G' THEN SET stringOut = CONCAT(stringOut , 'T');
WHEN 'g' THEN SET stringOut = CONCAT(stringOut , 't');
WHEN 'H' THEN SET stringOut = CONCAT(stringOut , 'U');
WHEN 'h' THEN SET stringOut = CONCAT(stringOut , 'u');
WHEN 'I' THEN SET stringOut = CONCAT(stringOut , 'V');
WHEN 'i' THEN SET stringOut = CONCAT(stringOut , 'v');
WHEN 'J' THEN SET stringOut = CONCAT(stringOut , 'W');
WHEN 'j' THEN SET stringOut = CONCAT(stringOut , 'w');
WHEN 'K' THEN SET stringOut = CONCAT(stringOut , 'X');
WHEN 'k' THEN SET stringOut = CONCAT(stringOut , 'x');
WHEN 'L' THEN SET stringOut = CONCAT(stringOut , 'Y');
WHEN 'l' THEN SET stringOut = CONCAT(stringOut , 'y');
WHEN 'M' THEN SET stringOut = CONCAT(stringOut , 'Z');
WHEN 'm' THEN SET stringOut = CONCAT(stringOut , 'z');
WHEN 'N' THEN SET stringOut = CONCAT(stringOut , 'A');
WHEN 'n' THEN SET stringOut = CONCAT(stringOut , 'a');
WHEN 'O' THEN SET stringOut = CONCAT(stringOut , 'B');
WHEN 'o' THEN SET stringOut = CONCAT(stringOut , 'b');
WHEN 'P' THEN SET stringOut = CONCAT(stringOut , 'C');
WHEN 'p' THEN SET stringOut = CONCAT(stringOut , 'c');
WHEN 'Q' THEN SET stringOut = CONCAT(stringOut , 'D');
WHEN 'q' THEN SET stringOut = CONCAT(stringOut , 'd');
WHEN 'R' THEN SET stringOut = CONCAT(stringOut , 'E');
WHEN 'r' THEN SET stringOut = CONCAT(stringOut , 'e');
WHEN 'S' THEN SET stringOut = CONCAT(stringOut , 'F');
WHEN 's' THEN SET stringOut = CONCAT(stringOut , 'f');
WHEN 'T' THEN SET stringOut = CONCAT(stringOut , 'G');
WHEN 't' THEN SET stringOut = CONCAT(stringOut , 'g');
WHEN 'U' THEN SET stringOut = CONCAT(stringOut , 'H');
WHEN 'u' THEN SET stringOut = CONCAT(stringOut , 'h');
WHEN 'V' THEN SET stringOut = CONCAT(stringOut , 'I');
WHEN 'v' THEN SET stringOut = CONCAT(stringOut , 'i');
WHEN 'W' THEN SET stringOut = CONCAT(stringOut , 'J');
WHEN 'w' THEN SET stringOut = CONCAT(stringOut , 'j');
WHEN 'X' THEN SET stringOut = CONCAT(stringOut , 'K');
WHEN 'x' THEN SET stringOut = CONCAT(stringOut , 'k');
WHEN 'Y' THEN SET stringOut = CONCAT(stringOut , 'L');
WHEN 'y' THEN SET stringOut = CONCAT(stringOut , 'l');
WHEN 'Z' THEN SET stringOut = CONCAT(stringOut , 'M');
WHEN 'z' THEN SET stringOut = CONCAT(stringOut , 'm');
END CASE;
SET v1 = v1 + 1;
END WHILE;
RETURN stringOut;
END;
How about something like...
SELECT SUBSTR('nopqrstuvwxyzabcdefghijklm',ASCII('b')-96,1);
I should point out that I've undertaken no research on this - so I might have misconstrued what rot13 is.

Hive Query issue - Invalid table alias or column reference

I have a query which contains Case statement and the output of the CASE is used to compare another column in Hive.I am not able to run the same query.Here is the query.
SELECT
AL1.RECORD_ID,
AL1.CARRIER_CODE,
AL1.ORIG_AP_CTY_CDE,
AL1.ORIG_STATE_CODE,
AL1.ORIG_COUNTRY_CODE,
AL1.ORIG_GEOGRAPHIC_ZONE_NUMBER,
CASE
WHEN AL1.ORIG_GEOGRAPHIC_ZONE_NUMBER > 99 THEN CONCAT(CAST(AL1.ORIG_GEOGRAPHIC_ZONE_NUMBER/10 AS INT), '0')
WHEN AL1.ORIG_GEOGRAPHIC_ZONE_NUMBER IN ('1','2','4','6','7','8','9') THEN '000'
ELSE AL1.ORIG_GEOGRAPHIC_ZONE_NUMBER
END AS ALL_ORIG_GEOGRAPHIC_ZONE,
AL1.ORIG_WORLD_AREA_NUMBER,
AL1.DEST_AP_CTY_CDE,
AL1.DEST_STATE_CODE,
AL1.DEST_COUNTRY_CODE,
AL1.DEST_GEOGRAPHIC_ZONE_NUMBER,
CASE
WHEN AL1.DEST_GEOGRAPHIC_ZONE_NUMBER > 99 THEN CONCAT(CAST(AL1.DEST_GEOGRAPHIC_ZONE_NUMBER/10 AS INT), '0')
WHEN AL1.DEST_GEOGRAPHIC_ZONE_NUMBER IN ('1','2','4','6','7','8','9') THEN '000'
ELSE AL1.DEST_GEOGRAPHIC_ZONE_NUMBER
END AS ALL_DEST_GEOGRAPHIC_ZONE,
AL1.DEST_WORLD_AREA_NUMBER,
AL1.FRBS_CDE,
AL1.OW_RT_CDE,
AL1.PUB_RULE_TRF_NUM,
AL1.FARE_RULE_NUM,
AL1.PUB_RTG_NUM,
AL1.PUB_FTNTE_ID_CDE,
AL1.FARE_TYPE_CODE,
AL1.SEASON_TYPE_CODE,
AL1.DAY_OF_WEEK_TYPE_CODE,
AL2.CATEGORY_CONTROL_ID,
AL2.CATEGORY_NUMBER AS GROUP_CATEGORY_NUMBER,
AL2.SEQUENCE_NUMBER,
AL2.LOCATION1_TYPE_CODE,
AL2.LOCATION1_CODE,
AL2.LOCATION2_TYPE_CODE,
AL2.LOCATION2_CODE,
AL2.FARE_CLASS_CODE,
AL2.GENERAL_RULE_TARIFF_NUMBER,
AL2.GENERAL_RULE_NUMBER,
AL2.GENERAL_RULE_IND,
'F' AS REC_IND
FROM TMP_TD_CNSTR_WINNING_FARES AL1
INNER JOIN TMP_TD_CNSTRPOST_CAT_CONTROL_ONLY_LIMITED_F AL2
ON (
AL1.CARRIER_CODE=AL2.CARRIER_CODE
AND AL1.PUB_RULE_TRF_NUM=AL2.TARIFF_NUMBER
AND AL1.FARE_RULE_NUM = AL2.RULE_FOOTNOTE_CODE
AND AL1.PUB_RTG_NUM = AL2.ROUTING_NUMBER
AND AL1.SEASON_TYPE_CODE = AL2.SEASON_TYPE_CODE
AND AL1.PUB_FTNTE_ID_CDE = AL2.FOOTNOTE_CODE
AND AL1.OW_RT_CDE = AL2.OW_RT_IND
AND AL1.FARE_TYPE_CODE = AL2.FARE_TYPE_CODE
AND AL1.DAY_OF_WEEK_TYPE_CODE = AL2. DAY_OF_WEEK_TYPE_CODE
)
INNER JOIN TMP_TD_CNSTRPOST_FRBS_MATCH_F AL4
ON ( AL1.CARRIER_CODE = AL4.CARRIER_CODE
AND AL1.PUB_RULE_TRF_NUM = AL4.PUB_RULE_TRF_NUM
AND AL1.FARE_RULE_NUM = AL4.RULE_NUM
AND AL1.FRBS_CDE = AL4.FRBS_CDE
AND AL2.FARE_CLASS_CODE = AL4.FARE_CLASS_CODE
)
WHERE
( (
(COALESCE(LOCATION1_TYPE_CODE, '') = '') OR
(LOCATION1_TYPE_CODE = 'C' AND LOCATION1_CODE = ORIG_AP_CTY_CDE) OR
(LOCATION1_TYPE_CODE = 'S' AND LOCATION1_CODE = ORIG_STATE_CODE) OR
(LOCATION1_TYPE_CODE = 'N' AND LOCATION1_CODE = ORIG_COUNTRY_CODE) OR
(LOCATION1_TYPE_CODE = 'Z' AND LOCATION1_CODE = ORIG_GEOGRAPHIC_ZONE_NUMBER) OR
(LOCATION1_TYPE_CODE = 'Z' AND LOCATION1_CODE = ALL_ORIG_GEOGRAPHIC_ZONE) OR
(LOCATION1_TYPE_CODE = 'A' AND LOCATION1_CODE = ORIG_WORLD_AREA_NUMBER)
)
AND
(
(COALESCE(LOCATION2_TYPE_CODE, '') = '') OR
(LOCATION2_TYPE_CODE = 'C' AND LOCATION2_CODE = DEST_AP_CTY_CDE) OR
(LOCATION2_TYPE_CODE = 'S' AND LOCATION2_CODE = DEST_STATE_CODE) OR
(LOCATION2_TYPE_CODE = 'N' AND LOCATION2_CODE = DEST_COUNTRY_CODE) OR
(LOCATION2_TYPE_CODE = 'Z' AND LOCATION2_CODE = DEST_GEOGRAPHIC_ZONE_NUMBER) OR
(LOCATION2_TYPE_CODE = 'Z' AND LOCATION2_CODE = ALL_DEST_GEOGRAPHIC_ZONE) OR
(LOCATION2_TYPE_CODE = 'A' AND LOCATION2_CODE = DEST_WORLD_AREA_NUMBER)
)
)
OR
((
(COALESCE(LOCATION1_TYPE_CODE, '') = '') OR
(LOCATION1_TYPE_CODE = 'C' AND LOCATION1_CODE = DEST_AP_CTY_CDE) OR
(LOCATION1_TYPE_CODE = 'S' AND LOCATION1_CODE = DEST_STATE_CODE) OR
(LOCATION1_TYPE_CODE = 'N' AND LOCATION1_CODE = DEST_COUNTRY_CODE) OR
(LOCATION1_TYPE_CODE = 'Z' AND LOCATION1_CODE = DEST_GEOGRAPHIC_ZONE_NUMBER) OR
(LOCATION1_TYPE_CODE = 'Z' AND LOCATION1_CODE = ALL_DEST_GEOGRAPHIC_ZONE) OR
(LOCATION1_TYPE_CODE = 'A' AND LOCATION1_CODE = DEST_WORLD_AREA_NUMBER)
)
AND
(
(COALESCE(LOCATION2_TYPE_CODE, '') = '') OR
(LOCATION2_TYPE_CODE = 'C' AND LOCATION2_CODE = ORIG_AP_CTY_CDE) OR
(LOCATION2_TYPE_CODE = 'S' AND LOCATION2_CODE = ORIG_STATE_CODE) OR
(LOCATION2_TYPE_CODE = 'N' AND LOCATION2_CODE = ORIG_COUNTRY_CODE) OR
(LOCATION2_TYPE_CODE = 'Z' AND LOCATION2_CODE = ORIG_GEOGRAPHIC_ZONE_NUMBER) OR
(LOCATION2_TYPE_CODE = 'Z' AND LOCATION2_CODE = ALL_ORIG_GEOGRAPHIC_ZONE) OR
(LOCATION2_TYPE_CODE = 'A' AND LOCATION2_CODE = ORIG_WORLD_AREA_NUMBER)
)
)
;
The error I am encountering is
FAILED: SemanticException [Error 10004]: Line 72:59 Invalid table alias or column reference 'ALL_ORIG_GEOGRAPHIC_ZONE
Please help me resolving the issue.Thanks in Advance!!
The where clause is evaluated before the select clause, so you can't use ALL_DEST_GEOGRAPHIC_ZONE in where clause.
You can try it in a derived table or having clause.
relevant question
Thanks Jerrick.It worked for me using derived table.Here is the updated query.
SELECT
*
FROM (SELECT
AL1.RECORD_ID,
AL1.CARRIER_CODE,
AL1.ORIG_AP_CTY_CDE,
AL1.ORIG_STATE_CODE,
AL1.ORIG_COUNTRY_CODE,
AL1.ORIG_GEOGRAPHIC_ZONE_NUMBER,
CASE
WHEN AL1.ORIG_GEOGRAPHIC_ZONE_NUMBER > 99 THEN CONCAT((CAST(AL1.ORIG_GEOGRAPHIC_ZONE_NUMBER / 10 AS int)), '0')
WHEN AL1.ORIG_GEOGRAPHIC_ZONE_NUMBER IN ('1', '2', '4', '6', '7', '8', '9') THEN '000'
ELSE AL1.ORIG_GEOGRAPHIC_ZONE_NUMBER
END AS ALL_ORIG_GEOGRAPHIC_ZONE,
AL1.ORIG_WORLD_AREA_NUMBER,
AL1.DEST_AP_CTY_CDE,
AL1.DEST_STATE_CODE,
AL1.DEST_COUNTRY_CODE,
AL1.DEST_GEOGRAPHIC_ZONE_NUMBER,
CASE
WHEN AL1.DEST_GEOGRAPHIC_ZONE_NUMBER > 99 THEN CONCAT((CAST(AL1.DEST_GEOGRAPHIC_ZONE_NUMBER / 10 AS int)), '0')
WHEN AL1.DEST_GEOGRAPHIC_ZONE_NUMBER IN ('1', '2', '4', '6', '7', '8', '9') THEN '000'
ELSE AL1.DEST_GEOGRAPHIC_ZONE_NUMBER
END AS ALL_DEST_GEOGRAPHIC_ZONE,
AL1.DEST_WORLD_AREA_NUMBER,
AL1.FRBS_CDE,
AL1.OW_RT_CDE,
AL1.PUB_RULE_TRF_NUM,
AL1.FARE_RULE_NUM,
AL1.PUB_RTG_NUM,
AL1.PUB_FTNTE_ID_CDE,
AL1.FARE_TYPE_CODE,
AL1.SEASON_TYPE_CODE,
AL1.DAY_OF_WEEK_TYPE_CODE,
AL2.CATEGORY_CONTROL_ID,
AL2.CATEGORY_NUMBER AS GROUP_CATEGORY_NUMBER,
AL2.SEQUENCE_NUMBER,
AL2.LOCATION1_TYPE_CODE,
AL2.LOCATION1_CODE,
AL2.LOCATION2_TYPE_CODE,
AL2.LOCATION2_CODE,
AL2.FARE_CLASS_CODE,
AL2.GENERAL_RULE_TARIFF_NUMBER,
AL2.GENERAL_RULE_NUMBER,
AL2.GENERAL_RULE_IND,
'F' AS REC_IND
FROM TMP_TD_CNSTR_WINNING_FARES AL1
INNER JOIN TMP_TD_CNSTRPOST_CAT_CONTROL_ONLY_LIMITED_F AL2
ON (
AL1.CARRIER_CODE = AL2.CARRIER_CODE
AND AL1.PUB_RULE_TRF_NUM = AL2.TARIFF_NUMBER
AND AL1.FARE_RULE_NUM = AL2.RULE_FOOTNOTE_CODE
AND AL1.PUB_RTG_NUM = AL2.ROUTING_NUMBER
AND AL1.SEASON_TYPE_CODE = AL2.SEASON_TYPE_CODE
AND AL1.PUB_FTNTE_ID_CDE = AL2.FOOTNOTE_CODE
AND AL1.OW_RT_CDE = AL2.OW_RT_IND
AND AL1.FARE_TYPE_CODE = AL2.FARE_TYPE_CODE
AND AL1.DAY_OF_WEEK_TYPE_CODE = AL2.DAY_OF_WEEK_TYPE_CODE
)
INNER JOIN TMP_TD_CNSTRPOST_FRBS_MATCH_F AL4
ON (AL1.CARRIER_CODE = AL4.CARRIER_CODE
AND AL1.PUB_RULE_TRF_NUM = AL4.PUB_RULE_TRF_NUM
AND AL1.FARE_RULE_NUM = AL4.RULE_NUM
AND AL1.FRBS_CDE = AL4.FRBS_CDE
AND AL2.FARE_CLASS_CODE = AL4.FARE_CLASS_CODE
)) AS WF
WHERE ((
(COALESCE(LOCATION1_TYPE_CODE, '') = '')
OR (LOCATION1_TYPE_CODE = 'C'
AND LOCATION1_CODE = ORIG_AP_CTY_CDE)
OR (LOCATION1_TYPE_CODE = 'S'
AND LOCATION1_CODE = ORIG_STATE_CODE)
OR (LOCATION1_TYPE_CODE = 'N'
AND LOCATION1_CODE = ORIG_COUNTRY_CODE)
OR (LOCATION1_TYPE_CODE = 'Z'
AND LOCATION1_CODE = ORIG_GEOGRAPHIC_ZONE_NUMBER)
OR (LOCATION1_TYPE_CODE = 'Z'
AND LOCATION1_CODE = WF.ALL_ORIG_GEOGRAPHIC_ZONE)
OR (LOCATION1_TYPE_CODE = 'A'
AND LOCATION1_CODE = ORIG_WORLD_AREA_NUMBER)
)
AND (
(COALESCE(LOCATION2_TYPE_CODE, '') = '')
OR (LOCATION2_TYPE_CODE = 'C'
AND LOCATION2_CODE = DEST_AP_CTY_CDE)
OR (LOCATION2_TYPE_CODE = 'S'
AND LOCATION2_CODE = DEST_STATE_CODE)
OR (LOCATION2_TYPE_CODE = 'N'
AND LOCATION2_CODE = DEST_COUNTRY_CODE)
OR (LOCATION2_TYPE_CODE = 'Z'
AND LOCATION2_CODE = DEST_GEOGRAPHIC_ZONE_NUMBER)
OR (LOCATION2_TYPE_CODE = 'Z'
AND LOCATION2_CODE = WF.ALL_DEST_GEOGRAPHIC_ZONE)
OR (LOCATION2_TYPE_CODE = 'A'
AND LOCATION2_CODE = DEST_WORLD_AREA_NUMBER)
)
)
OR ((
(COALESCE(LOCATION1_TYPE_CODE, '') = '')
OR (LOCATION1_TYPE_CODE = 'C'
AND LOCATION1_CODE = DEST_AP_CTY_CDE)
OR (LOCATION1_TYPE_CODE = 'S'
AND LOCATION1_CODE = DEST_STATE_CODE)
OR (LOCATION1_TYPE_CODE = 'N'
AND LOCATION1_CODE = DEST_COUNTRY_CODE)
OR (LOCATION1_TYPE_CODE = 'Z'
AND LOCATION1_CODE = DEST_GEOGRAPHIC_ZONE_NUMBER)
OR (LOCATION1_TYPE_CODE = 'Z'
AND LOCATION1_CODE = WF.ALL_DEST_GEOGRAPHIC_ZONE)
OR (LOCATION1_TYPE_CODE = 'A'
AND LOCATION1_CODE = DEST_WORLD_AREA_NUMBER)
)
AND (
(COALESCE(LOCATION2_TYPE_CODE, '') = '')
OR (LOCATION2_TYPE_CODE = 'C'
AND LOCATION2_CODE = ORIG_AP_CTY_CDE)
OR (LOCATION2_TYPE_CODE = 'S'
AND LOCATION2_CODE = ORIG_STATE_CODE)
OR (LOCATION2_TYPE_CODE = 'N'
AND LOCATION2_CODE = ORIG_COUNTRY_CODE)
OR (LOCATION2_TYPE_CODE = 'Z'
AND LOCATION2_CODE = ORIG_GEOGRAPHIC_ZONE_NUMBER)
OR (LOCATION2_TYPE_CODE = 'Z'
AND LOCATION2_CODE = WF.ALL_ORIG_GEOGRAPHIC_ZONE)
OR (LOCATION2_TYPE_CODE = 'A'
AND LOCATION2_CODE = ORIG_WORLD_AREA_NUMBER)
)
)
;

Why do I can't execute my string?

I create a string dynamically to perform this by EXECUTE. It throws an exception - why?
As you see I return my string before I try to execute it. When I run this result in a MySQL client instead of CALL procedure () it works flawlessly.
If I try to return my PREPAREd string I get no result. It seems PREPARE kinda breaks my string.
The exception
Error Code: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT movie_name, #ClearLOGOs:=IF((SELECT COUNT(image_id) FROM movie_images WHE' at line 1
The most important sql
SET set_part = CONCAT(set_part, '; ');
SET having_part = CONCAT(having_part, ' ORDER BY completeness ASC');
SET completeness_part = CONCAT(completeness_part, ') AS completeness');
SET complete_select = CONCAT('',set_part, select_part, completeness_part, ' FROM movie_items ',having_part);
SET #exec = complete_select;
SELECT #exec;
PREPARE _exec FROM #exec;
EXECUTE _exec;
The result (unformatted, exact copy)
SET #ClearLOGOs=0, #ClearART=0, #cdART=0, #Movie_Backgrounds=0, #Movie_Banner=0, #HD_Movie_Logos=0, #Movie_Thumbs=0, #HD_ClearART=0, #Movie_Poster=0; SELECT movie_name, #ClearLOGOs:=IF((SELECT COUNT(image_id) FROM movie_images WHERE image_active = 'y' AND image_type = '10' AND image_movie_tmdb_id = movie_tmdb_id) > 0, 0, 1) AS ClearLOGOs, #ClearART:=IF((SELECT COUNT(image_id) FROM movie_images WHERE image_active = 'y' AND image_type = '11' AND image_movie_tmdb_id = movie_tmdb_id) > 0, 0, 1) AS ClearART, #cdART:=IF((SELECT COUNT(image_id) FROM movie_images WHERE image_active = 'y' AND image_type = '12' AND image_movie_tmdb_id = movie_tmdb_id) > 0, 0, 1) AS cdART, #Movie_Backgrounds:=IF((SELECT COUNT(image_id) FROM movie_images WHERE image_active = 'y' AND image_type = '16' AND image_movie_tmdb_id = movie_tmdb_id) > 0, 0, 1) AS Movie_Backgrounds, #Movie_Banner:=IF((SELECT COUNT(image_id) FROM movie_images WHERE image_active = 'y' AND image_type = '19' AND image_movie_tmdb_id = movie_tmdb_id) > 0, 0, 1) AS Movie_Banner, #HD_Movie_Logos:=IF((SELECT COUNT(image_id) FROM movie_images WHERE image_active = 'y' AND image_type = '23' AND image_movie_tmdb_id = movie_tmdb_id) > 0, 0, 1) AS HD_Movie_Logos, #Movie_Thumbs:=IF((SELECT COUNT(image_id) FROM movie_images WHERE image_active = 'y' AND image_type = '24' AND image_movie_tmdb_id = movie_tmdb_id) > 0, 0, 1) AS Movie_Thumbs, #HD_ClearART:=IF((SELECT COUNT(image_id) FROM movie_images WHERE image_active = 'y' AND image_type = '26' AND image_movie_tmdb_id = movie_tmdb_id) > 0, 0, 1) AS HD_ClearART, #Movie_Poster:=IF((SELECT COUNT(image_id) FROM movie_images WHERE image_active = 'y' AND image_type = '29' AND image_movie_tmdb_id = movie_tmdb_id) > 0, 0, 1) AS Movie_Poster,(#ClearLOGOs + #ClearART + #cdART + #Movie_Backgrounds + #Movie_Banner + #HD_Movie_Logos + #Movie_Thumbs + #HD_ClearART + #Movie_Poster) AS completeness FROM movie_items HAVING ClearLOGOs > 0 OR ClearART > 0 OR cdART > 0 OR Movie_Backgrounds > 0 OR Movie_Banner > 0 OR HD_Movie_Logos > 0 OR Movie_Thumbs > 0 OR HD_ClearART > 0 OR Movie_Poster > 0 ORDER BY completeness ASC
You can't use more than one query within prepared statements.
SQL syntax for prepared statements does not support multi-statements (that is, multiple statements within a single string separated by “;” characters).
http://dev.mysql.com/doc/refman/5.0/en/sql-syntax-prepared-statements.html