postgresql 如何找到顶点的属性,其中包含一个值内的花括号,它遵循一种模式?

cx6n0qe3  于 2023-03-12  发布在  PostgreSQL
关注(0)|答案(1)|浏览(129)

我创建了一些顶点来表示MTG卡。每张卡都有一个属性mana_cost,它是在游戏中使用该卡的费用。mana_cost值存储在字符串的大括号中。例如,“{G}{G}”表示两个绿色魔法力,“{3}{G}{R}”表示您必须支付一个红色魔法力(红),一个绿色魔法值(绿)和3个任意颜色的魔法值(3)。
下面是我添加到图表中的一张生物牌的例子:

SELECT * FROM cypher ('MTG', $$
    CREATE (c:Creature {
        name: 'Slippery Bogle',
        set: 'Ultimate Masters (UMA)',
        card_number: 223, rarity: 'Uncommon',
        mana_cost: '{U/G}',
        artist: 'Jesper Ejsing',
        power: 1, toughness: 1,
        type: 'Beast',
        oracle_text: 'Hexproof (This creature can’t be the target of spells or abilities your opponents control.)',
        flavor_text: 'Ogle the bogle, or goggle the boggle? Doesn’t matter. You weren’t going to catch it anyway.'
})
RETURN c
$$) AS (creature agtype);

如果我想找到mana_cost小于或等于'{2}{G}'的牌,并且它可以找到光滑的博格尔(它的mana_cost是“{U/G},意思是它可以是一个绿色或蓝色的魔法力”),我该怎么做呢?

zujrkrfu

zujrkrfu1#

假设数字只出现在生物的魔法力消耗的第一个花括号{}中,下面是一个可能的解决方案:

SELECT * FROM cypher('MTG', $$
    MATCH (c)
    WHERE (size(c.mana_cost) < 9
            AND c.mana_cost CONTAINS 'G'
            AND (toInteger(substring(c.mana_cost, 1, 1)) <= 2
                OR toInteger(substring(c.mana_cost, 1, 1)) IS null))
        OR (size(c.mana_cost) = 9
            AND c.mana_cost CONTAINS 'G'
            AND (toInteger(substring(c.mana_cost, 1, 1)) <= 1
                OR toInteger(substring(c.mana_cost, 1, 1)) IS null))
    RETURN c.name
$$) AS (card agtype);

MATCH WHERE子句的第一部分考虑了长度小于9的魔法力费用,这是魔法力费用可以包含的最大字符数(例如{R}{U}{G})满足{2}{G}卡的阈值,AKA三张卡,至少有一张绿色。该查询首先搜索魔法力消耗包含字符G的生物,以满足至少需要一个绿色魔法力的生物的要求。然后,它获取第一组花括号{}之间的字符,并将该字符串转换为整数。如果结果整数小于或等于2,则将匹配该字符串。由于其中的字符可能不是数字而是字母,搜索还考虑产生null的结果。
MATCH WHERE子句的第二部分考虑了长度正好为9的法力消耗。这种情况需要稍微不同的条件来避免{3}{U}{G}这样的情况,{3}{U}{G}总共超过了3张牌的限制。如果第一个花括号包含数字,则限制为1,因此,当结果整数小于或等于1时,查询匹配结果整数。必须考虑产生null的转换子串,并且第一个花括号中的字符可能不总是数字。
最后输出满足这些条件的生物的名称。

相关问题