Php MySQL的最大价值是什么?
我将MySQL与PHP结合使用。这就像我的表:我使用了3个值,但还有更多 id | 1 | 2 | 3 ---+---+---+---- 1 | 3 |12 |-29 2 | 5 |8 |8 3 | 99|7 |NULL 我需要获取某行中最大值的列名。它应该得到: id | maxcol ---+------- 1 | 2 2 | 2 3 | 1Php MySQL的最大价值是什么?,php,mysql,row,Php,Mysql,Row,我将MySQL与PHP结合使用。这就像我的表:我使用了3个值,但还有更多 id | 1 | 2 | 3 ---+---+---+---- 1 | 3 |12 |-29 2 | 5 |8 |8 3 | 99|7 |NULL 我需要获取某行中最大值的列名。它应该得到: id | maxcol ---+------- 1 | 2 2 | 2 3 | 1 是否有任何查询可以做到这一点?我一直在尝试,但我无法让它正常工作。您是否正在寻找类似该功能的功能?例如: SELECT i
是否有任何查询可以做到这一点?我一直在尝试,但我无法让它正常工作。您是否正在寻找类似该功能的功能?例如:
SELECT id, GREATEST(col1, col2, col3)
FROM tbl
WHERE ...
将其与语句组合以获取列名:
SELECT id, CASE GREATEST(COALESCE(`1`, -2147483646), COALESCE(`2`, -2147483646), COALESCE(`3`, -2147483646))
WHEN `1` THEN 1
WHEN `2` THEN 2
WHEN `3` THEN 3
ELSE 0
END AS maxcol
FROM tbl
WHERE ...
这不漂亮。您最好按照Bill Karwin的建议进行规范化,或者干脆在PHP中处理这个问题
function findcol($cmp, $arr, $cols=Null) {
if (is_null($cols)) {
$cols = array_keys($arr);
}
$name = array_shift($cols);
foreach ($cols as $col) {
if (call_user_func($cmp, $arr[$name], $arr[$col])) {
$name = $col;
}
}
return $name;
}
function maxcol($arr, $cols=Null) {
return findcol(create_function('$a, $b', 'return $a < $b;'), $arr, $cols);
}
简单的回答是,没有简单的方法通过查询来实现这一点。您需要转换数据,然后以这种方式确定最大值。比如:
Select Id, ColumnName, Value
From (
Select '1' As ColumnName, Id, [1] As Value
From Table
Union All
Select '2', Id, [2]
From Table
Union All
Select '3', Id, [3]
From Table
) As Z
Where Exists(
Select 1
From (
Select '1' As ColumnName, Id, [1] As Value
From Table
Union All
Select '2', Id, [2]
From Table
Union All
Select '3', Id, [3]
From Table
) As Z2
Where Z2.Id = Z.Id
Group By Z2.Id
Having Max(Z2.Value) = Z.Value
)
Order By Id
此解决方案依赖于一组固定的列,在这些列中,您基本上命名UNIONALL查询中的列。此外,如果有两列具有相同Id的相同值,则会得到重复的行。此查询将返回最大值,而不考虑空值
SELECT MAX(value)
FROM
(SELECT 1 column_no, col1 value
FROM anotherunamedtable
UNION ALL
SELECT 2, col2
FROM anotherunamedtable
UNION ALL
SELECT 3, col3
FROM anotherunamedtable) t
如果您真的需要列号,那么
SELECT id,
(SELECT column_no
FROM
(SELECT 1 column_no, col1 value
FROM anotherunamedtable
WHERE id = t.id
UNION ALL
SELECT 2, col2
FROM anotherunamedtable
WHERE id = t.id
UNION ALL
SELECT 3, col3
FROM anotherunamedtable
WHERE id = t.id) s
ORDER BY max_value DESC
LIMIT 1)) as column_no
FROM anotherunamedtable t
但我认为最后一个查询可能执行得非常糟糕。
查询未经测试这是一个很好的例子,说明了规范化有助于简化查询设计。在中,您将创建另一个表,以便所有值都位于一列中的单独行上 由于已使用重复组跨三列存储值,因此可以通过以下方式找到值最大的列:
SELECT id, IF(col1>col2 AND col1>col3, 'col1', IF(col2>col3, 'col2', 'col3'))
AS column_with_greatest_value
FROM mytable;
在php端,您可以执行以下操作:
foreach ($rows as $key => $row) {
$bestCol = $best = -99999;
foreach ($row as $col => $value) {
if ($col == 'id') continue; // skip ID column
if ($value > $best) {
$bestcol = $col;
$best = $value;
}
}
$rows[$key]['best'] = $bestCol;
}
或者类似的东西…森林和树木,这里有一个简单而快速的解决方案,只要我没有摸索;表达式只查找行中最大的列
SELECT id,
CASE COALESCE(col1, -2147483648) >= COALESCE(col2, -2147483648)
WHEN
CASE COALESCE(col2, -2147483648) >= COALESCE(col3, -2147483648)
WHEN true THEN 1
ELSE
CASE COALESCE(col1, -2147483648) >= COALESCE(col3, -2147483648)
WHEN true THEN 1
ELSE 3
END
END
ELSE
CASE COALESCE(col2, -2147483648) >= COALESCE(col3, -2147483648)
WHEN true 2
ELSE 3
END
END
FROM table t
带有IF的版本可能更具可读性,但上面的应该会更好一些
为了处理空值,假设一个最小值为-2147483648的INT值,表达式可以重写以显式处理空值,但必须分为8种不同的情况,并留作操作练习。我看不出示例输出如何映射到显示的数据。你是说它应该返回1,99,2,12,3,8还是应该返回1,12,2,8,3,99?也就是说,它是向下还是横向查找最大值?它是查找最大值的列。因此,您需要每行具有最大值的列的索引或名称,对吗?对,因此第1行将输出2。因为它是12,最高点,如果我用PHP做呢?它必须允许负数和null…这非常接近:它得到最大的值,但我希望得到最大的列和该值。我相信这是正确的。警告-根据5.0.3,如果任何列为NULL,它将返回NULL;因此,必须使用合并到某个最小值,但如果所有空井都没有真正失败,则即使合并到某个最小值也会失败,但这与最小值实际存在于数据中并且是数据的最大值等情况是无法区分的。@Unreason:注意到GREATER对空值的处理。看起来很奇怪。明智的做法似乎是完全忽略空值,尤其是因为旧的行为似乎更好地只在所有值都为空时返回空值。不管怎样,如果我的评论/回答有用的话……啊,你输入得更快:我会给你+1,但我相信你有错误。与“澄清”相关的一个问题是“查找具有最大值的列”不精确,最好是在原始的“某行中最大值的列名”中,因此相关性不应在列名上,而应在列名上id@Unreason-你说得对。我应该在Id=2的输出中得到一个副本,我已经纠正了它。+1。我在设计阶段多想一点,可以节省以后的大量工作。@Patrick:-这句话让我想起了一句名言:数周的编码可以节省你数小时的计划时间。