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