所以我正在做一个收集卡管理应用程序,我有这些表:
当然,所有表都有一个唯一的自动增量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缺失,但可以通过其他卡片信息找到更低。
答案 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