我假設(shè)你原來查出N條數(shù)據(jù)的代碼如下:(你自己替換成你的)
10年積累的網(wǎng)站制作、成都網(wǎng)站建設(shè)經(jīng)驗,可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認識你,你也不認識我。但先做網(wǎng)站后付款的網(wǎng)站建設(shè)流程,更有獻縣免費網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
select * from tb order by col ;
現(xiàn)在你改成這樣:
SET @row_number =0;
select *, @row_number := @row_number+1 AS row_number
from tb
order by col;
--看到了吧 用變量來產(chǎn)生一個序列
--如果你要查詢特定值,可以這樣
select row_number
from (
select *, @row_number := @row_number+1 AS row_number
from tb
order by col) k
where 字段名='你要的字段值';
項目應(yīng)用中,曾有以下一個場景:
接口中要求發(fā)送一個int類型的流水號,由于多線程模式,如果用時間戳,可能會有重復(fù)的情況(當(dāng)然概率很小)。
所以想到了利用一個獨立的自增的sequence來解決該問題。
當(dāng)前數(shù)據(jù)庫為:mysql
由于mysql和oracle不太一樣,不支持直接的sequence,所以需要創(chuàng)建一張table來模擬sequence的功能,理由sql語句如下:
第一步:創(chuàng)建--Sequence 管理表
Java代碼
DROP TABLE IF EXISTS sequence;
CREATE TABLE sequence (
name VARCHAR(50) NOT NULL,
current_value INT NOT NULL,
increment INT NOT NULL DEFAULT 1,
PRIMARY KEY (name)
) ENGINE=InnoDB;
第二步:創(chuàng)建--取當(dāng)前值的函數(shù)
Java代碼
DROP FUNCTION IF EXISTS currval;
DELIMITER $
CREATE FUNCTION currval (seq_name VARCHAR(50))
RETURNS INTEGER
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE value INTEGER;
SET value = 0;
SELECT current_value INTO value
FROM sequence
WHERE name = seq_name;
RETURN value;
END
$
DELIMITER ;
第三步:創(chuàng)建--取下一個值的函數(shù)
Java代碼
DROP FUNCTION IF EXISTS nextval;
DELIMITER $
CREATE FUNCTION nextval (seq_name VARCHAR(50))
RETURNS INTEGER
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
UPDATE sequence
SET current_value = current_value + increment
WHERE name = seq_name;
RETURN currval(seq_name);
END
$
DELIMITER ;
第四步:創(chuàng)建--更新當(dāng)前值的函數(shù)
Java代碼
DROP FUNCTION IF EXISTS setval;
DELIMITER $
CREATE FUNCTION setval (seq_name VARCHAR(50), value INTEGER)
RETURNS INTEGER
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
UPDATE sequence
SET current_value = value
WHERE name = seq_name;
RETURN currval(seq_name);
END
$
DELIMITER ;
第五步:測試函數(shù)功能
當(dāng)上述四步完成后,可以用以下數(shù)據(jù)設(shè)置需要創(chuàng)建的sequence名稱以及設(shè)置初始值和獲取當(dāng)前值和下一個值。
INSERT INTO sequence VALUES ('TestSeq', 0, 1);----添加一個sequence名稱和初始值,以及自增幅度
SELECT SETVAL('TestSeq', 10);---設(shè)置指定sequence的初始值
SELECT CURRVAL('TestSeq');--查詢指定sequence的當(dāng)前值
SELECT NEXTVAL('TestSeq');--查詢指定sequence的下一個值
在java代碼中,可直接創(chuàng)建sql語句查詢下一個值,這樣就解決了流水號唯一的問題。
貼出部分代碼(已測試通過)
Java代碼
public void testGetSequence() {
Connection conn = JDBCUtils.getConnection(url, userName, password);
String sql = "SELECT CURRVAL('TestSeq');";
PreparedStatement ptmt = null;
ResultSet rs = null;
try {
ptmt = conn.prepareStatement(sql);
rs = ptmt.executeQuery();
int count = 0;
while (rs.next()) {
count = rs.getInt(1);
}
System.out.println(count);
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils.close(rs, ptmt, conn);
}
}
ps:在應(yīng)用中,還有一種用java代碼去實現(xiàn)模擬自增sequence的方式,具體思路是創(chuàng)建一張存放sequence的table,然后通過java調(diào)用sql語句去查詢和修改這個table中指定sequence名稱的值,這種方式請加上synchronized。具體代碼這里就不上傳了,因為實現(xiàn)了,未去測試過。
只能再查詢自增ID即可
具體操作:MYSQL獲取自增ID的四種方法
select max(id) from tablename
SELECT LAST_INSERT_ID() 函數(shù)
LAST_INSERT_ID 是與table無關(guān)的,如果向表a插入數(shù)據(jù)后,再向表b插入數(shù)據(jù),LAST_INSERT_ID會改變。
你可以寫一個存儲過程,相當(dāng)于自定義的函數(shù),不一定有現(xiàn)成的函數(shù)。