Обсуждение: LIKE, "=" and fixed-width character fields
Hello! There's table: CREATE TABLE table1 ( field1 CHARACTER(10), ... ); Then there's record: INSERT INTO table1(field1, ..) VALUES ('111', ...); Then I query it: SELECT * FROM table1 WHERE field1 <operator> '111'; When <operator> is LIKE no records matches query, when <operator> is = my record matches query. Why? And Does this behavior varies from PostgreSQL 7.4 to 8.1? -- A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing in e-mail?
Dmitry Teslenko wrote: > Hello! > There's table: > CREATE TABLE table1 ( > field1 CHARACTER(10), > ... > ); > > Then there's record: INSERT INTO table1(field1, ..) VALUES ('111', ...); > > Then I query it: > SELECT * FROM table1 WHERE field1 <operator> '111'; > > When <operator> is LIKE no records matches query, when <operator> is = > my record matches query. Why? And Does this behavior varies from > PostgreSQL 7.4 to 8.1? You're comparing a 3-character value '111' of type text to a 10-character one (whatever is in field1). That's probably not a sensible thing to do. You haven't got '111' as a value, you've got '111' with 7 trailing spaces. Search for that and you'll find it. It works for the '=' because the right-hand side will be converted to a character(10) before the comparison. You can't do that with LIKE because the right-hand side isn't characters, it's a pattern to search for. richardh=> SELECT * FROM chartbl WHERE c LIKE '111'; c --- (0 rows) richardh=> SELECT * FROM chartbl WHERE c LIKE '111 '; c ------------ 111 (1 row) richardh=> SELECT * FROM chartbl WHERE c LIKE '111%'; c ------------ 111 (1 row) -- Richard Huxton Archonet Ltd
Richard Huxton <dev@archonet.com> writes: > Dmitry Teslenko wrote: >> When <operator> is LIKE no records matches query, when <operator> is = >> my record matches query. Why? And Does this behavior varies from >> PostgreSQL 7.4 to 8.1? > You're comparing a 3-character value '111' of type text to a > 10-character one (whatever is in field1). That's probably not a sensible > thing to do. You haven't got '111' as a value, you've got '111' with 7 > trailing spaces. Search for that and you'll find it. Better yet: use varchar(n) not character(n). character(n) has no redeeming social value whatsoever. regards, tom lane
On Mon, Nov 10, 2008 at 18:14, Richard Huxton <dev@archonet.com> wrote: > Dmitry Teslenko wrote: >> Hello! >> There's table: >> CREATE TABLE table1 ( >> field1 CHARACTER(10), >> ... >> ); >> >> Then there's record: INSERT INTO table1(field1, ..) VALUES ('111', ...); >> >> Then I query it: >> SELECT * FROM table1 WHERE field1 <operator> '111'; >> >> When <operator> is LIKE no records matches query, when <operator> is = >> my record matches query. Why? And Does this behavior varies from >> PostgreSQL 7.4 to 8.1? > > You're comparing a 3-character value '111' of type text to a > 10-character one (whatever is in field1). That's probably not a sensible > thing to do. You haven't got '111' as a value, you've got '111' with 7 > trailing spaces. Search for that and you'll find it. > > It works for the '=' because the right-hand side will be converted to a > character(10) before the comparison. You can't do that with LIKE because > the right-hand side isn't characters, it's a pattern to search for. got it. > > richardh=> SELECT * FROM chartbl WHERE c LIKE '111'; > c > --- > (0 rows) > > richardh=> SELECT * FROM chartbl WHERE c LIKE '111 '; > c > ------------ > 111 > (1 row) > > richardh=> SELECT * FROM chartbl WHERE c LIKE '111%'; > c > ------------ > 111 > (1 row) > '111%' would also match '1111' and '111anything', wouldn't it? > -- > Richard Huxton > Archonet Ltd > On Mon, Nov 10, 2008 at 18:27, Tom Lane <tgl@sss.pgh.pa.us> wrote: > Richard Huxton <dev@archonet.com> writes: >> Dmitry Teslenko wrote: >>> When <operator> is LIKE no records matches query, when <operator> is = >>> my record matches query. Why? And Does this behavior varies from >>> PostgreSQL 7.4 to 8.1? > >> You're comparing a 3-character value '111' of type text to a >> 10-character one (whatever is in field1). That's probably not a sensible >> thing to do. You haven't got '111' as a value, you've got '111' with 7 >> trailing spaces. Search for that and you'll find it. > > Better yet: use varchar(n) not character(n). character(n) has no > redeeming social value whatsoever. > > regards, tom lane Okay, next time only varchars, but now I've got this db schema and no ability to change it. -- A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing in e-mail?
Dmitry Teslenko wrote: >> richardh=> SELECT * FROM chartbl WHERE c LIKE '111'; >> c >> --- >> (0 rows) >> >> richardh=> SELECT * FROM chartbl WHERE c LIKE '111 '; >> c >> ------------ >> 111 >> (1 row) >> >> richardh=> SELECT * FROM chartbl WHERE c LIKE '111%'; >> c >> ------------ >> 111 >> (1 row) >> > > '111%' would also match '1111' and '111anything', wouldn't it? Yes. I'm guessing what you actually want is varchar(10) rather than char(10) as a type. -- Richard Huxton Archonet Ltd