所以,我有一个表格(+----------+-------+
| id | order |
|----------+-------|
| 6c1e1f12 | 4 |
|----------+-------|
| 6c1e1f12 | 7 |
|----------+-------|
| 6c1e1f12 | 2 |
|----------+-------|
| 6c1e1f12 | 3 |
|----------+-------|
| 6c1e1f12 | 6 |
|----------+-------|
| 5d9f1892 | 5 |
|----------+-------|
| 5d9f1892 | 1 |
+----------+-------+
),如下所示:
order
我要做的是:"重置"每个现有id
记录组的+----------+-------+
| id | order |
|----------+-------|
| 6c1e1f12 | 0 |
|----------+-------|
| 6c1e1f12 | 1 |
|----------+-------|
| 6c1e1f12 | 2 |
|----------+-------|
| 6c1e1f12 | 3 |
|----------+-------|
| 6c1e1f12 | 4 |
|----------+-------|
| 5d9f1892 | 0 |
|----------+-------|
| 5d9f1892 | 1 |
+----------+-------+
值,从零(每次)开始。所以结果应该是:
12
我不介意实际的顺序 - 或者之前的行排序方式,例如,如果以前将order
作为0
的行变成了一行在此之后使用SELECT IF(@prev != a.id, @curr := 0, @curr := @curr + 1) AS order, @prev := a.id AS item_id
FROM (SELECT id FROM order_items, (SELECT @curr := 0, @prev := '') b ORDER BY id) a;
...等等。
我有这个查询以我想要的方式返回值:
UPDATE
...但我构建的order
查询只是将1
值设置为UPDATE order_items, (
SELECT IF(@prev != a.id, @curr := 0, @curr := @curr + 1) AS order, @prev := a.id as item_id
FROM (SELECT id FROM order_items, (SELECT @curr := 0, @prev := '') b ORDER BY id) a
) AS tmp
SET order_items.order = tmp.order
WHERE order_items.id = tmp.item_id;
,而不管:{/ p>
protected void writeTransaction()
{
DateTime todaysDate = DateTime.Now;
GridViewRow row = pickListGridview.SelectedRow;
TextBox trQty = row.FindControl("TextBox1") as TextBox;
string unitMeasure = row.Cells[6].Text;
string itemNum = row.Cells[1].Text;
string location = row.Cells[7].Text;
string ordNum = orderNumTextBox.Text.ToUpper();
OleDbCommand cmdWrite = new OleDbCommand("INSERT INTO TRDATA (ACREC, ACSEQ, ADJDT, ADJTM ,APCOD, APHMS, APRJC, BADGE, BLKSQ, CONO, CRWYN, CTLID, EFFIC, ENTUM, " +
"EXFLG, FDATE, IPLOC, ITNBR, LBTIM, LCQC2, LINSQ, LLOCN, LNKNO, LPQC1, MATIM, MSCST, MSQTY, MUCST, MUQTY, ODUDT, ORDNO, PARNT, PLIST, PNREF, QCNTR, QPIEC, QUEUE," +
" RJQTY, RLIST, RNREF, RSUPF, SCRAP, SDATE, SELYN, SEQNM, SHFTC, TCOST, TDATE, TRAMT, TRFMT, TRNA2, TRNN2, TRNC2, TRNNO, TRNNOO, TRQTY, TSTAT, TSTATS, TTIME, TURFA, " +
"TURFN, TURFC, TURNA, TURNN, TURNC, USER2, VRQTY, TRFG, ESHR, WTSK) " +
$"VALUES('Y', '0', '0', '0', 'I', '0', '0', '4153', '0', '0', 'N', '*', '0', '{unitMeasure}', '0', '1141208', '1', '{itemNum}', '0', '0', '0', '{location}', '0', '0', " +
$"'0', '0', '0', '0', '0', '0', '{ordNum}', '0', '0', '0', '0', '0', '1', '0', '0', '0', '0', '0', '0', '0', '29', '1', '0', '1171103', '0', 'IP', '0'," +
$" '0', '0', '8888889', '0', '{trQty.ToString()}', '2', '0', '85409', '0', '0', '0', '2', '8728517', '5', 'PPL000000017017', '0', '0', '0', '0')", cnTrData);
cnTrData.Open();
cmdWrite.ExecuteNonQuery();
cnTrData.Close();
}
This是一个带有初始架构和一些数据的SQL小提琴。
答案 0 :(得分:1)
MySQL参考手册警告用户定义变量的行为无法保证:
作为一般规则,除了在SET语句中,您不应该为用户变量赋值并在同一语句中读取值。 ...
您可能会得到您期望的结果,但这不能保证。 ...
涉及用户变量的表达式的评估顺序未定义。
https://dev.mysql.com/doc/refman/5.7/en/user-variables.html
注意到这一点,我们确实通过精心构造的SQL语句观察到一致的行为。
我使用了这种类型的模式,使用MySQL 5.6的用户定义变量成功。 (我希望在MySQL的未来版本中,对优化器进行改进后,这可能无法继续工作。
鉴于当前声明的目标,我倾向于这样写:
UPDATE (
SELECT @curr := IF(o.id <> @prev, 0, @curr + 1) AS order
, @prev := o.id AS item_id
, o.pk_col
FROM ( SELECT @curr := 0, @prev := '') i
CROSS
JOIN order_items o
ORDER BY o.id
) s
JOIN order_items t
ON t.pk_col = s.pk_col
SET t.order = s.order
我没有测试过这个特定的声明,但这是我使用的模式。
一些建议:
避免使用联接操作的逗号语法,而是使用JOIN
关键字。
确保ORDER BY
适用于正在进行评估并分配给用户定义变量的SELECT
。
对 使用表名或表别名限定所有列引用。 作为样式首选项,我将别名 我单独测试内联视图查询,以确保它返回我期望的结果。 如果此模式停止工作,如果我无法开始工作,那么我准备调整为使用中间临时表以确保在UPDATE之前实现视图查询。 使用用户定义的变量执行查询并实现 然后验证结果是否符合我的预期(在我执行UPDATE之前完成对用户定义变量的操作) 这种使用用户定义变量的方法特定于MySQL。其他数据库(例如SQL Server和Oracle)提供分析功能,例如 要做旧学校,没有用户定义的变量,没有分析函数,我们需要一个保证唯一的列(或一组列)。然后我们可以执行semijoin操作并获得“当前行”之前(小于)(之前)的行数。也就是说,我们想到“order”列表示“在此之前的行数”,因此第一行在它之前有0行,第二行在它之前有1行,等等。 *编辑* 随着SQLFiddle被添加到问题中,我们现在看到表 SQL Fiddle demonstration here: http://sqlfiddle.com/#!9/9caf62/1 IF
之外的udv进行分配(我希望首先评估IF
函数中的表达式,然后进行赋值。< / p>
s
分配给源(派生表/内联视图),并将别名t
分配给目标表(我正在更新的表) 。 DROP TEMPORARY TABLE IF EXISTS __tt_vq__ ;
CREATE TEMPORARY TABLE __tt_vq__ ( ... ) ;
INSERT INTO __tt_vq__ SELECT s.* FROM ( view query ) s ;
UPDATE __tt_vq__ s
JOIN target t
ON t.id = s.id
SET t.col = s.val
;
DROP TEMPORARY TABLE __tt_vq__ ;
ROW_NUMBER() OVER
或DENSE_RANK()
。我们使用用户定义的变量来模拟该功能。order_items
有一个item_id
列和一个id
列(实际上order
列名为rank
。 -- #####################################
-- added 2017-11-03 20:18:17 spencer7593
UPDATE (
SELECT @curr := IF(o.item_id <> @prev, 0, @curr + 1) AS rank
, @prev := o.item_id AS item_id
, o.id AS id
FROM ( SELECT @curr := 0, @prev := '') i
CROSS
JOIN order_items o
ORDER BY o.item_id, o.id
) s
JOIN order_items t
ON t.id = s.id
SET t.rank = s.rank