我很好奇如何以最一般的方式正式模拟SQLite的RPAD和LPAD函数。目标是能够做到
LPAD(column, character, repeat)
RPAD(column, character, repeat)
对于非常量表格列column
,character
,repeat
。如果character
和repeat
是已知常数,那么这将是一个好的,可行的解决方案:
但是如果上面的内容应该像这样执行怎么办:
SELECT LPAD(t.column, t.character, t.repeat) FROM t
SELECT LPAD(t.column, some_function(), some_other_function()) FROM t
SELECT LPAD(t.column, :some_bind_variable, :some_other_bind_variable) FROM t
如何通常模拟此LPAD
函数?我迷失了各种可能性:
相关问题:
答案 0 :(得分:17)
从http://verysimple.com/2010/01/12/sqlite-lpad-rpad-function/
复制-- the statement below is almost the same as
-- select lpad(mycolumn,'0',10) from mytable
select substr('0000000000' || mycolumn, -10, 10) from mytable
-- the statement below is almost the same as
-- select rpad(mycolumn,'0',10) from mytable
select substr(mycolumn || '0000000000', 1, 10) from mytable
答案 1 :(得分:4)
这对你来说更加肮脏:
X = padToLength
Y = padString
Z = expression
RPAD(对于LPAD,Z代替之后连接):
select
Z ||
substr(
replace(
replace(
substr(
quote(zeroblob(((X - length(Z) - 1 + length(Y)) / length(Y) + 1) / 2)),
3
),
"'",
""
),
"0",
Y
),
1,
(X - length(Z))
)
示例:
sqlite> select "foo" || replace(replace(substr(quote(zeroblob((2 + 1) / 2)), 3, (2 - length("foo"))), "'", ""), "0", "W");
foo
sqlite> select "foo" || replace(replace(substr(quote(zeroblob((7 + 1) / 2)), 3, (7 - length("foo"))), "'", ""), "0", "W");
fooWWWW
Sqlite意味着非常轻量级,所以我不得不对你对由于缺乏功能而感到“惊讶”的评论表示不同意见。但是,我同意应该有一种更简单的方法来填充,只是因为存在trim
函数。
答案 2 :(得分:4)
您也可以打印。
sqlite> SELECT PRINTF('%02d',5);
05
sqlite> SELECT PRINTF('%04d%02d',25,5);
002505
sqlite>
答案 3 :(得分:2)
@ user610650解决方案的一个简单版本,使用hex()代替quote(),除了字符填充外,还可以使用字符串填充:
X = padToLength
Y = padString
Z = expression
select
Z ||
substr(
replace(
hex(zeroblob(X)),
'00',
Y
),
1,
X - length(Z)
);
答案 4 :(得分:1)
JDBC /自定义函数方法(可能不适合您的确切情况,但可能可以进行调整)。使用来自{commics的SqliteJDBC Custom Functions和rightPad和leftPad函数的灵感.lang.Slang.StringUtils:
import java.sql.*;
import org.sqlite.Function;
public class Test
{
public static void main(String[] args)
{
Connection conn = getConnection();
conn.createStatement().execute("SELECT LPAD(t.column, t.character, t.repeat) FROM t");
conn.createStatement().execute("SELECT RPAD(t.column, t.character, t.repeat) FROM t");
conn.close();
}
public static Connection getConnection()
{
Class.forName("org.sqlite.JDBC");
Connection conn = DriverManager.getConnection("jdbc:sqlite:");
/* Left Padding UDF */
Function.create(conn, "LPAD", new Function()
{
protected void xFunc() throws SQLException
{
String text = value_text(0);
/* uses first character of supplied padding */
char paddingCharacter = value_text(1).charAt(0);
int repeat = value_int(2);
int padLength = repeat - text.length();
if(padLength <= 0)
{
result(text);
}
char[] padding = new char[padLength];
Array.fill(padding, paddingCharacter);
result(new String(padding).append(text));
}
});
/* Right Padding UDF */
Function.create(conn, "RPAD", new Function()
{
protected void xFunc() throws SQLException
{
String text = value_text(0);
/* uses first character of supplied padding */
char paddingCharacter = value_text(1).charAt(0);
int repeat = value_int(2);
int padLength = repeat - text.length();
if(padLength <= 0)
{
result(text);
}
char[] padding = new char[padLength];
Array.fill(padding, paddingCharacter);
result(text.append(new String(padding)));
}
});
}
}
(未经测试,关闭袖口,不处理空值等,但应概述这个想法......)
答案 5 :(得分:1)
她是一个简单的解决方案,使用CASE填充0-9,前导零。
sqlite> select id,week,year from bulletin where id = 67;
67|2|2014
select id,CASE WHEN length(week) = 2 THEN week
ELSE '0'||week
END AS week,year from bulletin where id = 67;
67|02|2014
答案 6 :(得分:0)
也许是这样的:
LPAD(@orig_text, @padding_char, @padding_length)
:
SELECT
SUBSTR(
REPLACE(
CAST(ZEROBLOB(@padding_length) AS TEXT),
CAST(ZEROBLOB(1) AS TEXT),
@padding_char
) + @orig_text,
-@padding_length,
@paadding_length
)
RPAD(@orig_text, @padding_char, @padding_length)
:
SELECT
SUBSTR(
@orig_text + REPLACE(
CAST(ZEROBLOB(@padding_length) AS TEXT),
CAST(ZEROBLOB(1) AS TEXT),
@padding_char
),
1,
@padding_length
)
答案 7 :(得分:0)
我绝对没有使用SQLite的经验,实际上我与SQLite3 db交互的时间少于三天。因此,我不确定我的发现能否对您的要求有所帮助。
我正在玩一个有趣的项目,该项目拥有所有可能的11位电话号码(3位话务员前缀+ 8位用户号码)。我的目标是用最少的存储资源创建某种数据库,但必须覆盖数据库上的所有可能数量。因此,我为8位订户创建了一个表,而另一个表包含3位公司前缀。最终编号将出现在连接两个表数据的视图上。让我专注于LOAD问题。由于订户表列为INT,因此它是0到99999999的单个记录。如果用户数少于10000000,则简单加入失败;值在10000000以下的所有订阅者订阅ID号都显示XXXprefix + 11,其中期望XXX000000 + 11。
在SQLite上使用LPAD / RPAD失败后,我找到了“ SUBSTR”!
看看下面的查询:
CREATE TABLE subs_num (
subscriber_num integer PRIMARY KEY
);
INSERT INTO subs_num values ('1');
INSERT INTO subs_num values ('10');
INSERT INTO subs_num values ('100');
INSERT INTO subs_num values ('1000');
SELECT subscriber_num from subs_num;
SELECT SUBSTR('00000000' || subscriber_num, -8, 8) AS SUBSCRIB_ID FROM subs_num;
现在,我认为您可以将SUBSTR用于您的LPAD / RPAD。
干杯!