我有一个包含NPC条目的MySQL表。每个NPC有3个能力位。每个插槽都有两个可能的值。
我正在尝试找到类似的NPC。类似意味着以下内容:每个NPC可以与这6种能力建立相同的能力组合。插槽是可互换的,但a和b值始终保持在一起。
示例:在下表中,NPC 40和41将类似。 NPC 42与它们不相似,因为它不能构建相同的能力组合,即使6个法术ID是相同的:
NPC 40和41可以使用技能:492 + 429 + 538;
NPC 42不能,因为492和429在同一个插槽中。
NPC
+-----+---------+---------+---------+---------+---------+---------+
| id | slot_1a | slot_1b | slot_2a | slot_2b | slot_3a | slot_3b |
+-----+---------+---------+---------+---------+---------+---------+
| 39 | 384 | 202 | 389 | 392 | 459 | 278 |
| 40 | 429 | 535 | 492 | 357 | 538 | 536 |
| 41 | 492 | 357 | 429 | 535 | 538 | 536 |
| 42 | 492 | 429 | 357 | 535 | 538 | 536 |
+-----+---------+---------+---------+---------+---------+---------+
如果我没弄错的话,类似的NPC有48种可能的组合。现在我想知道是否有更简单的解决方案来找到类似的NPC然后检查所有48种组合?
SQL小提琴(新数据):http://sqlfiddle.com/#!9/4c1aae/1
编辑:忘记提及,每个广告位的值也可以切换其位置。这可能是为什么@Kostas Mitsarakis不能100%工作的原因。
答案 0 :(得分:1)
我几乎可以肯定有更好的方法,但你可以试试这个。如果与其他插槽组合匹配,则必须检查每个插槽组合。
SELECT aa.npc_id, bb.npc_id
FROM npc AS aa, npc AS bb
WHERE
( (
aa.slot_1a = bb.slot_1a AND aa.slot_1b = bb.slot_1b)
OR (aa.slot_1a = bb.slot_2a AND aa.slot_1b = bb.slot_2b)
OR (aa.slot_1a = bb.slot_3a AND aa.slot_1b = bb.slot_3b)
)
AND
( (
aa.slot_2a = bb.slot_1a AND aa.slot_2b = bb.slot_1b)
OR (aa.slot_2a = bb.slot_2a AND aa.slot_2b = bb.slot_2b)
OR (aa.slot_2a = bb.slot_3a AND aa.slot_2b = bb.slot_3b)
)
AND
( (
aa.slot_3a = bb.slot_1a AND aa.slot_3b = bb.slot_1b)
OR (aa.slot_3a = bb.slot_2a AND aa.slot_3b = bb.slot_2b)
OR (aa.slot_3a = bb.slot_3a AND aa.slot_3b = bb.slot_3b)
)
AND aa.npc_id != bb.npc_id;
答案 1 :(得分:0)
可能不是最好的解决方案,但这就是我解决问题的方法:
SELECT group_concat( npc_id separator ','),
@slot1:= concat_ws(',',least(slot_1a,slot_1b),greatest(slot_1a,slot_1b)) AS slot1,
@slot2:= concat_ws(',',least(slot_2a,slot_2b),greatest(slot_2a,slot_2b)) AS slot2,
@slot3:= concat_ws(',',least(slot_3a,slot_3b),greatest(slot_3a,slot_3b)) AS slot3,
@min:=least(least(@slot1,@slot2),@slot3) as min,
@max:=greatest(greatest(@slot1,@slot2),@slot3) as max,
@med:=(
CASE
when @slot1 != @min and @slot1 != @max then @slot1
when @slot2 != @min and @slot2 != @max then @slot2
when @slot3 != @min and @slot3 != @max then @slot3
END
) AS med,
concat_ws(',',@min,@med,@max) AS move_set
FROM npc
GROUP by move_set