SQL / MYSQL - 通过另一个表中的效果过滤一个表中的项

时间:2017-05-21 09:03:12

标签: mysql sql

我想获得验证某些条件的项目的效果。被赋予效果存储在第二个表的行中。

  

表1结构:id,itemId,itemName,typeName,level

     

表2结构:id, effectId, itemId, effectName, min,max

我面临的主要问题是某些影响值得其他特定比例,我的条件必须反映。

到目前为止我建立的最佳查询:

SELECT i.name,i.level,i.typeName
FROM `effects` AS e,`items` AS i
WHERE `effectId` IN (111,125,126,138) AND i.itemId=e.itemId AND i.typeId IN (1) AND (`level` BETWEEN 150 AND 200)
GROUP BY i.itemId
HAVING count(distinct `effectId`) >= 3
ORDER BY SUM(CASE e.effectId WHEN 138 THEN e.max*0.2 ELSE e.max END) 
DESC,i.level DESC

我对此查询的两个主要问题是,我无法明确表达必须条件和等价:项目可以111 and 125 and 126 but no 138,而必须有138, 125 or 111, 126 or 111

编辑:请求的项目必须有138,126和125,但111可以加起来或替换126或125。 所以一个正确的项目可以有: (138126125111) (138126111) (138125111) (138126125) (138,111)

我可以订购结果,但我必须进行其他查询才能获得不会保留第一个查询顺序的效果值。

我希望我已经足够了,如果您需要更多信息,请询问。 谢谢你的阅读。

2 个答案:

答案 0 :(得分:0)

我回顾一下:该项目必须

  • 有效138
  • 具有效果111或者125和126

因此HAVING条款必须付诸实践:

SELECT i.name, i.level, i.typeName
FROM items i
JOIN effects e ON e.itemId = i.itemId
WHERE i.typeId IN (1) 
  AND i.level BETWEEN 150 AND 200
  AND e.effectId IN (111,125,126,138)
GROUP BY i.itemId
HAVING SUM(e.effectId = 138) > 0
AND
(
  SUM(e.effectId = 111) > 0 
  OR 
  (SUM(e.effectId = 125) > 0 AND SUM(e.effectId = 126) > 0)
)
ORDER BY SUM(CASE e.effectId WHEN 138 THEN e.max*0.2 ELSE e.max END) DESC, i.level DESC;

这使用了MySQL的真值= 1 / false = 0。

答案 1 :(得分:0)

Thorsten Kettner通过向我展示正确的语法和HAVING关键字提供的可能性,帮助我找到了我想要的答案。

我想通过存储在第二个表格中的效果来过滤表格中的项目,然后显示所选项目的效果。

复杂性来自于一种效应可能产生相反的效果,以及具有特定比率的等效效果(或更多)。

最后,它只需要将所有具有Case的SUM,然后将SUM添加到SELECT,HAVING和ORDER BY(但是对于ORDER BY,您将SUM在SELECT中分离的所有效果和HAVING)。

以下是php构建查询的一个示例:

SELECT i.name, i.level, i.typeName,
    SUM(CASE e.effectId WHEN 178 THEN e.max WHEN 179 THEN -1*e.max END) as effect,
    SUM(CASE e.effectId WHEN 126 THEN e.max WHEN 155 THEN -1*e.max WHEN 138 THEN 1*e.max  END) as effect2
FROM items i
JOIN effects e ON e.itemId = i.itemId
WHERE i.typeId IN ('16') 
    AND i.level BETWEEN 1 AND 200
    AND e.effectId IN (178,126,155,138)
GROUP BY i.itemId
HAVING
    SUM(CASE e.effectId WHEN 178 THEN e.max WHEN 179 THEN -1*e.max END) > 0 
    AND SUM(CASE e.effectId WHEN 126 THEN e.max WHEN 155 THEN -1*e.max WHEN 138 THEN 1*e.max  END) >0 
ORDER BY SUM(CASE e.effectId WHEN 178 THEN e.max WHEN 179 THEN -1*e.max WHEN 126 THEN e.max WHEN 155 THEN -1*e.max WHEN 138 THEN 1*e.max   END),
i.level DESC
LIMIT 50

非常感谢Thorsten Kettner!