2

この sqlfiddle リンクは、呼び出し間で状態を保持しているようです: http://sqlfiddle.com/#!2/125bc/1

これには、mysql の次のスキーマが含まれています。

CREATE TABLE if not exists  `standings` (
  `teamid` int(11) NOT NULL,
  `win` decimal(23,0) default NULL,
  `tie` decimal(23,0) default NULL,
  `lose` decimal(23,0) default NULL,
  PRIMARY KEY  (`teamid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;


INSERT INTO `standings` (`teamid`, `win`, `tie`, `lose`) VALUES
(1, 3, 0, 0),
(2, 1, 1, 1),
(3, 1, 1, 1),
(4, 0, 0, 3);


CREATE TABLE if not exists `newscores` (
  `recordid` int(11) NOT NULL auto_increment,
  `teamid` int(11) NOT NULL,
  `gameid` int(11) NOT NULL,
  `totalstrokes` int(11) NOT NULL,
  primary key (recordid)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;



INSERT INTO `newscores` (`recordid`, `teamid`, `gameid`, `totalstrokes`) VALUES
(5, 1, 1, 145),
(6, 2, 1, 105),
(7, 5, 1, 145),
(8, 6, 1, 155);

およびこれらの 2 つのクエリ:

Insert into  standings (teamid, win, tie, lose) (SELECT g1.teamid, SUM( IF( g1.totalstrokes < g2.totalstrokes, 1, 0 ) ) AS win, SUM( IF( g1.totalstrokes = g2.totalstrokes, 1, 0 ) ) AS tie, SUM( IF( g1.totalstrokes > g2.totalstrokes, 1, 0 ) ) AS lose
FROM newscores g1
JOIN newscores g2 ON g1.gameid = g2.gameid
AND g1.teamid != g2.teamid
GROUP BY g1.teamid) 
on duplicate key 
update win = win + values(win), 
lose = lose + values(lose), 
tie = tie + values(tie);

select * from standings;

standings次の表が表示されます。

teamid   win tie lose
  1       4   1   1
  2       4   1   1
  3       1   1   1
  4       0   0   3
  5       1   1   1
  6       0   0   3

そして、初めて実行されます。(URL を新しいウィンドウに貼り付けて) 2 回目に実行すると、チーム ID 1、2、5、6 の値の一部が増分されます。

スキーマを編集して「テーブルの作成」を「存在しない場合のテーブルの作成」に変更するか、その逆に変更するか、「テーブルの削除」ステートメントを含めることで、リセットできます。しかし、これは非常に奇妙に思えます。

PS この質問に sqlfiddle タグを追加したよりも、誰かがより有意義であればありがたいです。

4

1 に答える 1

17

私は SQL Fiddle の作成者です。この動作には非常に簡単な説明があります。基本的に、右側のパネル (「クエリの実行」側) で実行するすべてのクエリはトランザクション ブロックで実行され、すぐにロールバックされてスキーマの状態が維持されます (左側のパネルで定義されているとおり)。パネル)。ほとんどの場合、トランザクションで実行されたほとんどすべてがロールバックできるため、すべてが元の場所に戻されます。ただし、SQL Fiddle で早い段階で発見したように、ロールバックされない数少ないものの 1 つは、ID 値の自動インクリメントです。これは、すべてのベンダーによる意図的な設計上の決定であり、主キーが再利用によって衝突しないようにするためのものです。

自動IDは無意味であると想定されているため、SQL Fiddleにとって、この1つの変更が問題になることはありませんでした(特に、ほとんどの人は挿入を左側で実行するため)。

複数のウィンドウを開かなくても、この動作を確認できます。ところで、[クエリの実行] を複数回押すだけで、変化することがわかります。また、SQL Server のサンプル フィドルでも確認できます 。(特定のフィドルが使用されなくなった後、実行中のDBを削除してメモリを解放するため、フィドルがしばらく使用されていないとリセットされます)。

編集

どっ!申し訳ありませんが、クエリを十分に読んでいませんでした。私は今何が起こっているかを見ています。InnoDB の代わりに MyISAM テーブルを使用しています。MySQLのオプションとしてそれらを無効にする必要があります。ご覧のとおり、トランザクションはまったくサポートされていません。そのため、これらのテーブルへの更新をロールバックしようとすると、更新がロールバックされません。それらを増やし続けます。MySQL はデフォルトで MyISAM を使用するため、最初に MySQL をオプションとして展開したときにこれを見ました。トランザクションを機能させるには、デフォルトを InnoDB に変更する必要がありました。

ここでは、MyISAM の明示的な使用を削除しただけで正常に動作していることがわかります: http://sqlfiddle.com/#!2/cec6e/1

アップデート

以下は、MySQL の要件がいくつか変更されたため、少しアレンジし直したバージョンです: http://sqlfiddle.com/#!2/a9cc3/1

于 2012-05-15T18:18:34.250 に答える