这是我的表结构,这里我需要交换项目。这意味着,你可以看到类型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
进一步提供帮助
我给你提供表格结构和测试数据,如果你有想法与我分享!
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 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或任何其他方式来做到这一点。
答案 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)
之前的解决方案 - 不良解决方案
编辑:在这种情况下,我认为解决方案确实不可行。即使你有可能重新排序项目(并非总是如此),可能会发生更快过期的项目将在稍后过期的项目之后。
你能做什么:
答案 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