【问题标题】:MYSQL - SELECT row with lowest value and other conditions, or a fallback with highestMYSQL - 选择具有最低值和其他条件的行,或者具有最高值的回退
【发布时间】:2012-04-28 08:05:39
【问题描述】:

这里似乎有很多帖子在问类似的问题,但我还没有找到可以帮助我解决问题的帖子。

我正在尝试选择具有 最低 值的行,其中其他三个条件必须为真或回退到另一组条件,给定一个变量 (uc) 并选择最高价格。

Table: level (sample data)
id  |price  |copies |used   |uc
--------------------------------------
1   |7      |10     |10     |charlie01
2   |17     |10     |8      |charlie01
3   |37     |5      |5      |charlie01
4   |47     |10     |9      |charlie01
7   |5      |15     |9      |charlie02
8   |15     |15     |0      |charlie02
9   |35     |15     |0      |charlie02
10  |45     |15     |0      |charlie02
11  |3      |5      |5      |charlie03
12  |13     |5      |5      |charlie03

结果: 编辑结果 - charlie01 应该是 2

VARIABLE    |RESULTING ROW
--------------------------
charlie01   |2
charlie02   |7
charlie03   |12

### 开始伪代码:###

选择最低 price 的行,其中used 小于copiesused 大于0uc 等于VARIABLE 或如果否结果(这意味着所有used 都等于copies)选择具有最高价格的行,其中used 等于copiesuc 等于VARIABLE

SELECT * 
FROM level
WHERE

    (
        used < copies
        AND used > 0
        AND uc = *VARIABLE*
    )
 ### OR IF NO RESULTS ###
    (
        used = copies
        AND uc = *VARIABLE*
    )

ORDER BY price ASC
LIMIT 1

### END 伪代码###

这是我写的查询(以uccharlie01为例):

SELECT *
FROM (
    SELECT *
    FROM `level` 
    WHERE 
        ((
        `used` < `copies`
        AND `used` > '0'
        )
        OR
        (
        `used` = `copies`
        ))
        AND `uc` = 'charlie01'
        ORDER BY `price` ASC

        ) AS T
ORDER BY `used` ASC
LIMIT 1

由于记录3,它不适用于示例数据,即使used = copies。这是因为used on record 3 &lt; used on record 2 (the row we want, because it has the lowest price)

我知道 MAX() 存在,并在最后一个小时尝试使用它,但没有成功,我真的不认为我理解它是如何工作的,它似乎只是在选择整列的最大值无论如何...?

现在,我已经在圈子里添加了条件等,但我认为我需要做一个 JOIN 某种类型的,但我不确定从哪里开始。你认为我应该如何处理这个查询?

编辑:我真的很抱歉,当我实际上试图选择最低价格时,我才意识到我说的是最高价格 used copies 但如果全部 used = 最高价格copies

干杯
查理

【问题讨论】:

  • 但是第4行使用
  • Sh*t 我很抱歉,我才意识到我说的是最高价格,而我实际上是在尝试选择使用过的最低价格
  • :) 如果你更改结果表,我将更改代码 sn-p
  • 结果表现在是正确的,我确定 :) 再次抱歉 >.
  • 我撤回了我的答案,因为它不能解决问题,但是如果我能想到可以解决的问题,我会再次发布。

标签: php mysql join max


【解决方案1】:

如果您正在使用此代码编写生产代码,我会等待更好的答案,但有几个有趣的选项可能对您有用...

SELECT * FROM (
  SELECT *, (used < copies and used > 0) AS copies_avail FROM level
  ORDER BY copies_avail desc, IF(copies_avail, price, -price) ASC
) AS x GROUP BY uc;

(如果要在 where 子句中指定 uc,可以只使用内部部分)

更有趣的类似选项(尽量不要说 hackish =p)

SELECT * FROM (
  SELECT * FROM level 
  ORDER BY IF(used < copies AND used > 0, price, -price + 10000) ASC
) AS x GROUP BY uc;

(其中 10000 远高于表中的任何预期价格)

无论如何...相信这两个的输出都与您编辑的结果相匹配,但在性能方面可能很糟糕。如果您确实卡在做这样的事情,您可能可以将copys_avail 查询结果存储在表中以避免文件排序?

另外,对 used = 0 且副本 > 0 的情况感到好奇 - 从您的描述中无法判断它是否应该使用 price asc 或 price desc 组进行排序。在这些示例中,它是价格描述。

【讨论】:

  • 谢谢您,这两个查询都完全按照我的需要工作:) 您能否详细说明有关存储copys_avail 的部分?您的意思是存储一个标志 (1|0) 以避免对所有内容进行排序吗?实现这一点的最佳方法是什么?
  • 嘿查理,我认为将(used &lt; copies AND used &gt; 0) 逻辑存储在数据库中可能会节省一些查询的复杂性,但实际上并不确定,因为我们也在 order by 上使用 price。
猜你喜欢
  • 2019-08-05
  • 1970-01-01
  • 1970-01-01
  • 2020-07-23
  • 2022-01-01
  • 2021-04-26
  • 2013-05-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多