mysql交换带行号的项目

时间:2011-04-15 10:17:42

标签: php mysql arrays swap

这是我的表结构,这里我需要交换项目。这意味着,你可以看到类型3总是配对(type 3 items are always paired)。  我刚刚命名配对项目,以便理解对中的第一个是主,第二个是子。 So master of the pair should not come 5,10 and 15 positions 如果到了那个地方我需要将下一个项目交换到那个地方(neaxt项目将是sub它不应被视为下一个项目)

例如

pid 10 (comes in 10 position) i need to swap it like this
pid   type  name
..     ..   ..
10      2    B2

11      3    E1(master) 
12      3    A2(sub)

..     ..   ..

 pid    type    pname
  1       1     A
  2       1     B
  3       2     C
  4       3     D(mater)
  5       3     E(sub)

  6       1     A1
  7       2     B1
  8       1     C1
  9       2     D1
  10      3     E1(master)    

  11      3     A2(sub)
  12      2     B2  
  13      1     C2
  14      2     D2
  15      1     E3 

截图

  1. perfect placement
  2. Collapsed design
  3. 进一步提供帮助

    我给你提供表格结构和测试数据,如果你有想法与我分享!

    创建查询

    CREATE TABLE IF NOT EXISTS `table_swap1` (
        `pid` int(11) NOT NULL AUTO_INCREMENT,
        `type` int(11) NOT NULL,
        `name` varchar(50) NOT NULL,
        PRIMARY KEY (`pid`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=17;
    

    INSERT QUERY

    INSERT INTO `table_swap1` (`pid`, `type`, `name`) VALUES
        (1, 1, 'A'),(2, 1, 'B'),(3, 2, 'D'),(4, 3, 'E(master)'),
        (5, 3, 'f(sub)'),(6, 1, 'A1'),(7, 2, 'B1'),(8, 1, 'C1'),
        (9, 2, 'D1'),(10, 3, 'E1(master)'),(11, 3, 'A2(sub)'),(12, 2, 'B2'),
        (13, 1, 'C2'),(14, 2, 'D2'), (15, 1, 'E2');
    

    我的工作和结果

      SELECT aa.pid, (
    
        CASE aa.pid
        WHEN bb.apid
        THEN bb.atype
        WHEN bb.bpid
        THEN bb.btype
        WHEN bb.cpid
        THEN bb.ctype
        ELSE aa.type
        END
        )
        TYPE , (
    
        CASE aa.pid
        WHEN bb.apid
        THEN bb.aname
        WHEN bb.bpid
        THEN bb.bname
        WHEN bb.cpid
        THEN bb.cname
        ELSE aa.name
        END
        )name
        FROM (
    
        SELECT a.pid +1 apid, a.TYPE atype, a.NAME aname,
               b.pid +1 bpid, b.type btype, b.name bname,
               c.pid -2 cpid, c.type ctype, c.name cname
        FROM table_swap1 a, table_swap1 b, table_swap1 c
        WHERE MOD( a.pid, 5 ) =0
        AND a.pid +1 = b.pid
        AND a.type =3
        AND a.type = b.type
        AND a.pid +2 = c.pid
        )bb, table_swap1 aa
        GROUP BY pid
    
      

    此查询完成了我真正需要的内容   ...但在我的情况下,pid是主键。   所以我无法在1到15中得到结果   订单。那我可以这个行号吗...   我该怎么办

    欢迎所有类型的建议甚至解决方案在PHP中 让我可以用mysql或任何其他方式来做到这一点。

5 个答案:

答案 0 :(得分:2)

所以,基本上你的问题可以表述为:

The first product of two adjacent products of type 3 cannot be placed 
in a position which is a multiple of 5.

使事情变得复杂的是,您的表中没有订单,没有订单,就无法为您的产品定义一个恒定的“位置”。没有指定ORDER BY的SELECT返回行的顺序。

无论如何,最简单的方法是在应用程序中。将您的结果作为一个数组抓取,扫描它,如果您发现两个产品不在正确的位置,只需将它们在阵列中随机播放。

答案 1 :(得分:1)

之前的解决方案 - 不良解决方案


编辑:在这种情况下,我认为解决方案确实不可行。即使你有可能重新排序项目(并非总是如此),可能会发生更快过期的项目将在稍后过期的项目之后。

你能做什么:

  1. 在所有情况下,您需要为每个主+子对使用一个条目。
    1. 制作一个表product_list(prodid,subid),其中subid对于非产品表可以为null
    2. 加入产品表产品一次以获取主产品,第二次加入sub(告诉我您是否需要查询)和group by product_list.prodid
  2. 显示产品 - 选择其中一个
    1. 制作一个设计,允许您将2个项目放在一个方格中。
    2. 点击“奖励产品”按钮,弹出或javascript动画显示其他产品
    3. 鼠标悬停时
    4. 根据位置向右或向左展开产品。

答案 2 :(得分:1)

我认为你需要重新设计你的表以避免交换行 - 记住,行的顺序在关系表中应该是无关紧要的,而mySQL是一个关系数据库。

这是一个可能的重新设计 - 虽然让我知道我是否正确理解你的问题:

Table product
-------------
pid
---
name
type

Table productPair
-----------------
pid*
---
part1*
part2*

当产品是盒子中的一对时,您可以使用相同的键将其作为产品和产品对输入。通过适当的约束,您可以对设计进行建模,以便配对仅由一种类型1和一种类型2产品组成。

一些示例数据:

+------------------+
|product           |
+------------------+
|PID |type  |name  |
+----+------+------+
|1   |1     |A     |
|2   |1     |B     |
|3   |2     |C     |
|4   |3     |D     |
|5   |3     |E     |
+----+------+------+

+------------------+
|productPair       |
+------------------+
|PID*|part1*|part2*|
+----+------+------+
|4   |1     |3     |
|5   |2     |3     |
+----+------+------+

在这种形式中,不需要行顺序,关系编码每对的性质,而不是表中数据的位置。

答案 3 :(得分:1)

是的,我还建议你在这里重新设计,但是对于quik-n-dirty结果,只需添加一些类似this的SQL:

select
    table_swap1.*,
    @row_number := @row_number + 1 as row_number,
    0 = mod(@row_number, 5) is_fifth
from
    table_swap1,
    (SELECT @row_number := 0) tmp
;

答案 4 :(得分:1)

我的环境是SQL Server。我用这种语法编写了我的解决方案......我将尝试在MySQL中重写(在SQL Server原文下面),但我相信你会理解我的观点(无论我是否正确重写)。基本上,使用bb子查询来建立未指定的连接(笛卡尔积),以便每个pid行的master落在5的倍数上,可用于所有其他行,然后将匹配(受影响的相邻行)的行重新计算到Resequence列中。如果我正确理解您的数据,您甚至可能会遗漏type=3 AND短语。

SELECT (CASE 
WHEN aa.pid = bb.pid THEN aa.pid+1
WHEN aa.pid-1=bb.pid THEN aa.pid+1
WHEN aa.pid-2=bb.pid THEN aa.pid-2
ELSE aa.pid END) ResequencePid
, aa.pid, aa.type, aa.name
FROM table_swap1 aa, 
(SELECT pid FROM table_swap1 WHERE type=3 AND pid%5=0 AND name LIKE '%(master)') bb
/* optional */ ORDER BY 1

/* MySQL version */

SELECT (CASE
WHEN aa.pid = bb.pid THEN aa.pid+1
WHEN aa.pid-1=bb.pid THEN aa.pid+1
WHEN aa.pid-2=bb.pid THEN aa.pid-2
ELSE aa.pid END) ResequencePid
, aa.pid, aa.type, aa.name
FROM table_swap1 aa, 
(SELECT pid FROM table_swap1 WHERE type=3 AND MOD(pid, 5)=0 AND name LIKE '%(master)') bb
/* optional */ ORDER BY 1