MySQL:基于另一个字段添加序列列

发布于 2024-08-08 15:50:18 字数 669 浏览 2 评论 0原文

我正在处理一些遗留代码/数据库,并且需要向数据库添加一个字段,该字段将记录与该(外国)id 相关的序列号。

示例表数据(当前):

ID     ACCOUNT     some_other_stuff
1      1           ...
2      1           ...
3      1           ...
4      2           ...
5      2           ...
6      1           ...

我需要添加一个sequenceid列,该列为每个帐户单独递增,实现:

ID     ACCOUNT     SEQ     some_other_stuff
1      1           1       ...
2      1           2       ...
3      1           3       ...
4      2           1       ...
5      2           2       ...
6      1           4       ...

请注意,序列与帐户相关。

有没有办法可以在 SQL 中实现此目的,或者我是否可以使用 PHP 脚本来完成这项工作?

TIA, 凯夫

I'm working on some legacy code/database, and need to add a field to the database which will record a sequence number related to that (foreign) id.

Example table data (current):

ID     ACCOUNT     some_other_stuff
1      1           ...
2      1           ...
3      1           ...
4      2           ...
5      2           ...
6      1           ...

I need to add a sequenceid column which increments separately for each account, achieving:

ID     ACCOUNT     SEQ     some_other_stuff
1      1           1       ...
2      1           2       ...
3      1           3       ...
4      2           1       ...
5      2           2       ...
6      1           4       ...

Note that the sequence is related to account.

Is there a way I can achieve this in SQL, or do I resort to a PHP script to do the job for me?

TIA,
Kev

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

帅的被狗咬 2024-08-15 15:50:18

创建触发器:

CREATE TRIGGER trg_mytable_bi
BEFORE INSERT ON mytable
FOR EACH ROW
BEGIN
      DECLARE nseq INT;
      SELECT  COALESCE(MAX(seq), 0) + 1
      INTO    nseq
      FROM    mytable
      WHERE   account = NEW.account;
      SET NEW.seq = nseq;
END;

Create a trigger:

CREATE TRIGGER trg_mytable_bi
BEFORE INSERT ON mytable
FOR EACH ROW
BEGIN
      DECLARE nseq INT;
      SELECT  COALESCE(MAX(seq), 0) + 1
      INTO    nseq
      FROM    mytable
      WHERE   account = NEW.account;
      SET NEW.seq = nseq;
END;
喵星人汪星人 2024-08-15 15:50:18

问题被标记为“mysql”,所以是的,MySQL 的 auto_increment 可以创建分组顺序 id。
参见http://dev.mysql.com/doc/ refman/5.0/en/example-auto-increment.html

对于 MyISAMBDB 表,您可以在多列中的辅助列上指定 AUTO_INCREMENT指数。在这种情况下,AUTO_INCRMENT 列的生成值的计算方式为 MAX(auto_increment_column) + 1 WHERE prefix=given-prefix。当您想要将数据放入有序组时,这非常有用。

编辑:示例 php 脚本(使用 PDO,但它与 php-mysql 模块)

$pdo = new PDO('mysql:host=...;dbname=...', '...', '...'); 
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

// example table
$pdo->exec(
  'CREATE TEMPORARY TABLE Foo (
    id int auto_increment,
    account int,
    someotherstuff varchar(32),
    primary key(account,id)
  ) engine=MyIsam'
);
// insert example data
$stmt = $pdo->prepare('INSERT INTO Foo (account,someotherstuff) VALUES (?,?)');
$stmt->execute(array(1, '1a'));
$stmt->execute(array(1, '1b'));
$stmt->execute(array(1, '1c'));
$stmt->execute(array(2, '2a'));
$stmt->execute(array(2, '2b'));
$stmt->execute(array(1, '1d'));
unset($stmt);

// query data
foreach( $pdo->query('SELECT account,id,someotherstuff FROM Foo') as $row ) {
  echo $row['account'], ' ', $row['id'], ' ', $row['someotherstuff'], "\n";
}

打印

1 1 1a
1 2 1b
1 3 1c
2 1 2a
2 2 2b
1 4 1d

The question is tagged as "mysql", so yes, MySQL's auto_increment can create groupwise sequential ids.
see http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html:

For MyISAM and BDB tables you can specify AUTO_INCREMENT on a secondary column in a multiple-column index. In this case, the generated value for the AUTO_INCREMENT column is calculated as MAX(auto_increment_column) + 1 WHERE prefix=given-prefix. This is useful when you want to put data into ordered groups.

edit: example php script (using PDO, but it's the same game with the php-mysql module)

$pdo = new PDO('mysql:host=...;dbname=...', '...', '...'); 
$pdo->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

// example table
$pdo->exec(
  'CREATE TEMPORARY TABLE Foo (
    id int auto_increment,
    account int,
    someotherstuff varchar(32),
    primary key(account,id)
  ) engine=MyIsam'
);
// insert example data
$stmt = $pdo->prepare('INSERT INTO Foo (account,someotherstuff) VALUES (?,?)');
$stmt->execute(array(1, '1a'));
$stmt->execute(array(1, '1b'));
$stmt->execute(array(1, '1c'));
$stmt->execute(array(2, '2a'));
$stmt->execute(array(2, '2b'));
$stmt->execute(array(1, '1d'));
unset($stmt);

// query data
foreach( $pdo->query('SELECT account,id,someotherstuff FROM Foo') as $row ) {
  echo $row['account'], ' ', $row['id'], ' ', $row['someotherstuff'], "\n";
}

prints

1 1 1a
1 2 1b
1 3 1c
2 1 2a
2 2 2b
1 4 1d
献世佛 2024-08-15 15:50:18

这应该可行,但可能很慢:

CREATE temporary table seq ( id int, seq int);
INSERT INTO seq ( id, seq )
    SELECT id, 
      (SELECT count(*) + 1 FROM test c 
      WHERE c.id < test.id AND c.account = test.account) as seq 
    FROM test;

UPDATE test INNER join seq ON test.id = seq.id SET test.seq = seq.seq;

我已将表称为“测试”;显然这需要正确设置。您必须使用临时表,因为 MySQL 不允许您使用正在更新的同一个表中的子查询。

This should work but is probably slow:

CREATE temporary table seq ( id int, seq int);
INSERT INTO seq ( id, seq )
    SELECT id, 
      (SELECT count(*) + 1 FROM test c 
      WHERE c.id < test.id AND c.account = test.account) as seq 
    FROM test;

UPDATE test INNER join seq ON test.id = seq.id SET test.seq = seq.seq;

I have called the table 'test'; obviously that needs to be set correctly. You have to use a temporary table because MySQL will not let you use a subselect from the same table you are updating.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文