删除记录时减少单元格

时间:2015-12-31 05:07:48

标签: php mysql

所以我有一个简单的MySQL表(块):

SELECT * FROM `block` WHERE 1 ORDER BY `year`, `month`, `day`, `block`;

id      year    month day block te status
20000   2015    12  28  1   100000  1
20001   2015    12  28  2   100000  1
20002   2015    12  28  3   100001  1
20003   2015    12  28  4   100001  1
20004   2015    12  29  1   100001  1
20005   2015    12  29  2   100001  1
20006   2015    12  29  3   100002  1
20066   2015    12  30  1   100003  1
20078   2015    12  30  1   100007  1
20070   2015    12  30  1   100004  1
20067   2015    12  30  2   100003  1
20071   2015    12  30  2   100004  1
20079   2015    12  30  2   100007  1
20072   2015    12  30  3   100004  1
20080   2015    12  30  3   100007  1
20068   2015    12  30  3   100003  1
20069   2015    12  30  4   100003  1
20073   2015    12  30  4   100004  1
20074   2015    12  31  1   100004  1
20075   2015    12  31  1   100000  1
20076   2015    12  31  2   100000  1
20077   2015    12  31  3   100000  1
20007   2016    1   1   1   100017  1
20008   2016    1   1   2   100017  1
20009   2016    1   1   3   100017  1

我的问题是,如果删除连续的行部分,如何将所有剩余的行移出?

例如,如果删除2015-12-28的所有块,我希望所有剩余的块递减以占用计划中未使用的块。

如果这令人困惑或不清楚,请告诉我。感谢。

2 个答案:

答案 0 :(得分:0)

我认为需要更多背景知识。你的最终目标是什么?

两个选项......

第一个选项

查看下面有关MySQL编号行的链接。你可以使用这样的东西来使你的块动态。 http://www.xaprb.com/blog/2006/12/02/how-to-number-rows-in-mysql/

第二选项

如果您在白天提取数据,只需按id的顺序提取数据,您就可以假设在您使用数据的任何应用程序中这些块都是有序的。

答案 1 :(得分:0)

  

例如,如果删除2015-12-28的所有块,我希望所有剩余的块递减以占用计划中未使用的块。

您实际上并未指定递减的含义。我想你想在所有的块中移动日期。但是看看这里:

<item
    android:id="@+id/action_filter"
    android:title="test"
    android:icon="@drawable/inbox"
    mytest:showAsAction="always" />

我们在2015-12-28有4个区块,在2015-12-29有3个区块。假设我们删除了四个28。怎么了? 29个中的三个转移到28个,30个转为29个?或者做三个29和30个班次来填补28&#39所留下的四个位置?

根据策略,您需要选择不同的策略。也许你应该定义究竟是什么,以及什么数据在&#34;块&#34;之外,并提供一些转移的例子(具有不同的天数 - 例如,28 28 29 30并且你删除了两个28.顺便说一下,你能只删除一个吗?如果是,那会发生什么呢?)。

假设每个日期可以包含固定数量的记录

例如,您可以先计算要删除的行数

20000   2015    12  28  1   100000  1
20001   2015    12  28  2   100000  1
20002   2015    12  28  3   100001  1
20003   2015    12  28  4   100001  1

20004   2015    12  29  1   100001  1
20005   2015    12  29  2   100001  1
20006   2015    12  29  3   100002  1
20066   2015    12  30  1   100003  1

然后选择具有较晚日期的下一个项目。然后你转移它们,但是你需要迭代地做这个(一旦29&s已经消失,30&#39s将会转移,依此类推)。计算可能会非常昂贵。

但在这种情况下,您可以将日期与数据分开:

SELECT COUNT(*) FROM ... WHERE day=28 AND month=12 AND year=2015

现在你需要以这样的方式加入表格,好吧,加入它们。 无论他们的基数。您可能拥有比TableB更长的TableA,反之亦然。

在某些RDBMS中这很容易。在MySQL中,它非常糟糕(你甚至不能使用CREATE VIEW来简化语法,因为你需要在视图中使用变量或子查询),对于小数据集,你可以使用#39 ;最好选择TableA,然后选择TableB,并在PHP中使用一个循环:

TableA
2015 12 28
2015 12 28
2015 12 28

TableB
20000 100000 1
20001 100000 1

结果可能是(简化)

// Run the query from tableA to get the dates
$TableADataSet = array();
while ($tuple = SQLFetch($rs)) {
    $TableADataSet = $tuple;
}

// Run the query from tableB to get the rest
$TableBDataSet = array();
while ($tuple = SQLFetch($rs)) {
    $TableBDataSet = $tuple;
}

// Now put them together.

for (;;) {
    if (empty($TableADataSet)) {
        if (empty($TableBDataSet)) {
            break;
        }
        $TupleA = $EmptyRowFormattedAsTableA;
        $TupleB = array_pop($TableBDataSet);
    } else {
        $TupleA = array_pop($TableADataSet);
        if (empty($TableBDataSet)) {
            $TupleB = $EmptyRowFormattedAsTableB;
        } else {
            $TupleB = array_pop($TableBDataSet);
        }
    }
    // Now you have a row with dates and data "aligned".
    // Missing data are taken by the sample rows EmptyRowFormattedAs... .
}

如果删除RowB,行的最右边部分会向上移动:

2015 12   28      RowA
2015 12   28      RowB
2015 12   29      RowC
NULL NULL NULL    RowD

在MySQL中,您首先需要对行进行编号,而您没有2015 12 28 RowA 2015 12 28 RowC 2015 12 29 RowD RECNO()函数,所以就像

一样
ROW_NUMBER()

并使用行号获取日期。

SELECT @a:=@a+1 AS ranka,data1.* FROM ( SELECT * FROM TableA ORDER BY year, month, day ) AS data1, (SELECT @a:=0) AS init1;

您对TableB也这样做。但现在你必须做&#34;水平连接&#34;特技。我们可以处于以下三种情况之一:

1   2015 12 28
2   2015 12 28
3   2015 12 29

&#34; A B&#34;我们可以通过JOIN得到的部分。 &#34; A - &#34;部分我们得到LEFT JOIN与B is longer A is longer Same length A B A B A B A B A B A B - B A - A B 。 &#34; - B&#34;我们得到一个正确的联接WHERE TableB.primarykey IS NULL。最后,我们将它与UNION一起放在一起。 这三个查询需要使用上面的尴尬语法

所有这些(非常复杂的)查询是

WHERE TableA.primarykey IS NULL

从性能的角度来看,这可能是一场生猪。