如何确定MySQL中组的第一个结果?

时间:2018-01-30 17:27:40

标签: mysql sql group-by

所以我正在做一个收集卡管理应用程序,我有这些表:

  • “card”:包含所有制作的不同卡片,并提供其信息(ID,名称,文字等)
  • “edition”:包含所有已发布的卡片集(称为“edition”,因为“set”是一个保留字)
  • “cardinset”:由于卡片可以出现在多个集合中,因此这是两者之间的关联表格。它还给出了套装中卡片的编号以及我用法文(fr)和英文(en)中的卡片的数量。

当然,所有表都有一个唯一的自动增量ID,称为“id”。

我的SQL请求的目的是列出集合中的所有卡片,按照集合中卡片的数量排序。我需要“cardinset”条目(number,fr,en)的所有信息,当然还有“card”条目的信息(名称,稀有度等),但我还需要知道每张卡的份数我总共(在所有集合中,而不仅仅是在这一集中)。

我的SQL请求看起来像这样(我删除了一些不重要的字段):

SELECT
    c.name,
    c.rarity,
    SUM(cis.fr) + SUM(cis.en) AS available,
    cis.number,
    cis.fr,
    cis.en
FROM
    card AS c 
    INNER JOIN cardinset AS cis ON c.id = cis.cardId 
WHERE
    c.id IN
    ( 
        SELECT
            cardId 
        FROM
            cardinset AS cs 
        WHERE
            setId = 104 
        ORDER BY
            number
    ) 
GROUP BY
    c.id,
    c.name 
ORDER BY
    cis.number

它几乎可以工作,但它不会为每张卡检索正确的cardinset条目,因为它占据了组中的第一个,这并不总是链接到右侧组的那个。

示例:

| c.name         | c.rarity | available | cis.number | cis.fr | cis.en |
| -------------- | -------- | --------- | ---------- | ------ | ------ | 
| Divine Verdict | Common   | 9         | 008        | 1      | 1      |

此处,卡信息(名称和稀有度)是正确的,以及“可用”字段。然而,顺式字段是错误的:它们是将此卡与另一组连接的顺式条目的一部分。

问题是:是否可以定义哪个条目是组中的第一个条目,因此在这种情况下返回?如果没有,是否有另一种方式(可能更干净)来获得我想要的结果?

提前感谢您的回答,我真的不知道该怎么做......我想我已经达到了MySQL的知识限制......

这是一个更精确的例子。这个screenshot n°1显示了我的查询的第一个结果(如上所述),知道总共有212个结果。它们应按编号排序,每个数字应该只有一个结果,但也有一些例外:

n°005,应该是“Divine Verdict”不存在,因为它显示为n°008.那是因为该卡是6个不同集合的一部分,我们可以在screenshot n°2中看到(查询“SELECT * FROM cardinset WHERE cardId = 13984”的结果,并且该组返回第一个条目,该条目用于设置n°12而不是n°104,就像我所拥有的那样。然而,“可用”字段显示“9”,这是我想要的结果:它出现的所有6个集合中该卡的所有“fr”和“en”字段的总和。

还有其他卡没有正确的卡片信息:n°011和019缺失,但可以通过其他卡片信息找到更低。

2 个答案:

答案 0 :(得分:1)

我相信这是您希望格式化查询的方式。

SELECT
    c.name,
    c.rarity,
    cis.fr + cis.en AS available,
    cis.number,
    cis.fr,
    cis.en
FROM
    card AS c 
INNER JOIN cardinset AS cis ON c.id = cis.cardId 
WHERE
c.id IN
( 
    SELECT
        cardId 
    FROM
        cardinset AS cs 
    WHERE
        setId = 104 
    GROUP BY
        setID, cardID
) 
ORDER BY
    cis.number

GROUP BY子句被移动到子选择并被修改以确保条目是卡/集的正确组合。还删除了SUM,因为这不是必需的。

答案 1 :(得分:0)

我终于做到了! 我使用子查询来获得"可用"带有GROUP BY子句的字段。它很长,而且不是很快,但它完成了工作。如果你有一个可以改善它的想法,请不要犹豫。

SELECT e.code, cs.number, sub.name, sub.rarity, cs.fr, cs.en, sub.available
FROM cardinset as cs
INNER JOIN edition as e ON e.id = cs.setId
INNER JOIN (
    SELECT c.id, c.name, c.rarity,
        SUM(cis.fr)+SUM(cis.en) as available, SUM(cis.frused)+SUM(cis.enused) as used
    FROM card as c
    INNER JOIN cardinset as cis ON c.id = cis.cardId 
    WHERE c.id IN ( 
        SELECT cardId 
        FROM cardinset as cins
        WHERE setId = 54)
    GROUP BY c.id, c.name
    ORDER BY c.id
    ) AS sub ON cs.cardId = sub.id
WHERE setId = 54
ORDER BY cs.number