Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 从多个列中选择“最小值”或“最大值”所在的id_Php_Mysql_Sql_Pdo - Fatal编程技术网

Php 从多个列中选择“最小值”或“最大值”所在的id

Php 从多个列中选择“最小值”或“最大值”所在的id,php,mysql,sql,pdo,Php,Mysql,Sql,Pdo,我正在寻找一个快速的MySQL查询,它返回与所有价格类别(a、b、c和d)相比,具有最低(min)或最高(max)价格的产品id) 我有一个名为“巧克力库存”的产品表,有几个价格类别。从特定类别(a或b或c或d)收到最低(min)或最高(max)价格非常容易 价格类别为十进制(10,2)。下面是一个示例,它返回类别中的最高价格,但不返回id: $t = 'chocolate_stock'; $arrIds = array(1, 3); $strQuery = "SELECT id,

我正在寻找一个快速的MySQL查询,它返回与所有价格类别(
a、b、c
d
)相比,具有最低(
min
)或最高(
max
)价格的产品id

我有一个名为“巧克力库存”的产品表,有几个价格类别。从特定类别(
a
b
c
d
)收到最低(
min
)或最高(
max
)价格非常容易

价格类别为十进制(10,2)。下面是一个示例,它返回类别中的最高价格,但不返回id:

$t = 'chocolate_stock';
$arrIds = array(1, 3);

$strQuery = "SELECT id, 
             MAX(price_a) AS price_a, 
             MAX(price_b) AS price_b, 
             MAX(price_c) AS price_c, 
             MAX(price_d) AS price_d 
             FROM $t WHERE id IN(". implode(',', array_map('intval', $arrIds)) .")";

检索此信息的最快方法是什么?

您无法获取id,因为MAX返回一个值。但id不是这样。您可以使用单独的查询,如

SELECT id,MAX(price_a) FROM $t WHERE id IN (". implode(',', array_map('intval', $arrIds)).")";
SELECT id,MAX(price_b) FROM $t WHERE id IN (". implode(',', array_map('intval', $arrIds)).")";

etc

您没有获得id,因为MAX返回一个值。但id不是这样。您可以使用单独的查询,如

SELECT id,MAX(price_a) FROM $t WHERE id IN (". implode(',', array_map('intval', $arrIds)).")";
SELECT id,MAX(price_b) FROM $t WHERE id IN (". implode(',', array_map('intval', $arrIds)).")";

etc

如果您将希望输出的内容制成表格,可能会有所帮助,但我认为您缺少的是HAVING子句

首先,试试这个

select min(id), max(price_a) from $t having price_a = max(price_a)
然后试试看

select min(id), min(price_a) from $t having price_a = min(price_a)
union
select min(id), max(price_a) from $t having price_a = max(price_a)

如果您将希望输出的外观制成表格,可能会有所帮助,但我认为您缺少的部分是HAVING子句

首先,试试这个

select min(id), max(price_a) from $t having price_a = max(price_a)
然后试试看

select min(id), min(price_a) from $t having price_a = min(price_a)
union
select min(id), max(price_a) from $t having price_a = max(price_a)

此查询符合您的要求:

(select t.*
 from $t t
 where . . .
 order by price_a desc
 limit 1) union all
 (select t.*
 from $t t
 where . . .
 order by price_b desc
 limit 1) union all
(select t.*
 from $t t
 where . . .
 order by price_c desc
 limit 1) union all
(select t.*
 from $t t
 where . . .
 order by price_d desc
 limit 1)
如果您在
id
上有一个索引,那么它的性能应该相当好

这种方法需要对表进行四次遍历(尽管
id
上的索引应该会大大降低这一点)。以下方法只需通过表格一次:

select MAX(price_a),
       substring_index(group_concat(id order by price_a desc), ',', 1),
       max(price_b),
       substring_index(group_concat(id order by price_b desc), ',', 1),
       max(price_c),
       substring_index(group_concat(id order by price_c desc), ',', 1),
       max(price_d),
       substring_index(group_concat(id order by price_d desc), ',', 1)
from $t
where . . .

它使用
group_concat()
substring_index()
的技巧来获取每个列的最大id

此查询满足您的要求:

(select t.*
 from $t t
 where . . .
 order by price_a desc
 limit 1) union all
 (select t.*
 from $t t
 where . . .
 order by price_b desc
 limit 1) union all
(select t.*
 from $t t
 where . . .
 order by price_c desc
 limit 1) union all
(select t.*
 from $t t
 where . . .
 order by price_d desc
 limit 1)
如果您在
id
上有一个索引,那么它的性能应该相当好

这种方法需要对表进行四次遍历(尽管
id
上的索引应该会大大降低这一点)。以下方法只需通过表格一次:

select MAX(price_a),
       substring_index(group_concat(id order by price_a desc), ',', 1),
       max(price_b),
       substring_index(group_concat(id order by price_b desc), ',', 1),
       max(price_c),
       substring_index(group_concat(id order by price_c desc), ',', 1),
       max(price_d),
       substring_index(group_concat(id order by price_d desc), ',', 1)
from $t
where . . .

它使用
group_concat()
substring_index()
的技巧来获取每个列的最大id

您要做的第一件事是规范化数据,为了便于以后查询,我将创建以下视图:

CREATE VIEW NormalT
AS
    SELECT  ID, Name, 'Price_a' AS Type, Price_a AS Price
    FROM    T
    UNION ALL
    SELECT  ID, Name, 'Price_b' AS Type, Price_b AS Price
    FROM    T
    UNION ALL
    SELECT  ID, Name, 'Price_c' AS Type, Price_c AS Price
    FROM    T
    UNION ALL
    SELECT  ID, Name, 'Price_d' AS Type, Price_d AS Price
    FROM    T;
那么我不确定您想要的格式,如果您想要每个价格的最小值和最大值,您可以使用以下内容:

SELECT  mt.Type2,
        mt.Type,
        mt.Price,
        t.ID,
        t.Name
FROM    (   SELECT  Type, MIN(Price) AS Price, 'MIN' AS Type2
            FROM    NormalT
            GROUP BY Type
            UNION ALL
            SELECT  Type, MAX(Price) AS Price, 'MAX' AS Type2
            FROM    NormalT
            GROUP BY Type
        ) mt
        INNER JOIN NormalT T
            ON mt.Type = T.Type
            AND mt.Price = t.Price
ORDER BY mt.Type2, mt.Type, t.ID;
SELECT  mt.Type2,
        t.Type,
        mt.Price,
        t.ID,
        t.Name
FROM    (   SELECT  MIN(Price) AS Price, 'MIN' AS Type2
            FROM    NormalT
            UNION ALL
            SELECT  MAX(Price) AS Price, 'MAX' AS Type2
            FROM    NormalT
        ) mt
        INNER JOIN NormalT T
            ON mt.Price = t.Price;
将从示例数据中输出以下内容:

TYPE2   TYPE        PRICE   ID  NAME
MAX     Price_a     250     1   Chips Ahoy
MAX     Price_a     250     2   Chocolate Chunk
MAX     Price_b     530     1   Chips Ahoy
MAX     Price_c     720     1   Chips Ahoy
MAX     Price_d     850     3   Oreo
MIN     Price_a     103     3   Oreo
MIN     Price_b     44.52   3   Oreo
MIN     Price_c     32.92   2   Chocolate Chunk
MIN     Price_d     110     2   Chocolate Chunk
但是,如果它只是所有价格(a、b、c和d)的最小值和最大值,则可以使用:

SELECT  mt.Type2,
        mt.Type,
        mt.Price,
        t.ID,
        t.Name
FROM    (   SELECT  Type, MIN(Price) AS Price, 'MIN' AS Type2
            FROM    NormalT
            GROUP BY Type
            UNION ALL
            SELECT  Type, MAX(Price) AS Price, 'MAX' AS Type2
            FROM    NormalT
            GROUP BY Type
        ) mt
        INNER JOIN NormalT T
            ON mt.Type = T.Type
            AND mt.Price = t.Price
ORDER BY mt.Type2, mt.Type, t.ID;
SELECT  mt.Type2,
        t.Type,
        mt.Price,
        t.ID,
        t.Name
FROM    (   SELECT  MIN(Price) AS Price, 'MIN' AS Type2
            FROM    NormalT
            UNION ALL
            SELECT  MAX(Price) AS Price, 'MAX' AS Type2
            FROM    NormalT
        ) mt
        INNER JOIN NormalT T
            ON mt.Price = t.Price;
将输出以下内容:

TYPE2   TYPE    PRICE       ID  NAME
MIN     Price_c     32.92   2   Chocolate Chunk
MAX     Price_d     850     3   Oreo

您要做的第一件事是规范化数据,为便于以后查询,我将创建以下视图:

CREATE VIEW NormalT
AS
    SELECT  ID, Name, 'Price_a' AS Type, Price_a AS Price
    FROM    T
    UNION ALL
    SELECT  ID, Name, 'Price_b' AS Type, Price_b AS Price
    FROM    T
    UNION ALL
    SELECT  ID, Name, 'Price_c' AS Type, Price_c AS Price
    FROM    T
    UNION ALL
    SELECT  ID, Name, 'Price_d' AS Type, Price_d AS Price
    FROM    T;
那么我不确定您想要的格式,如果您想要每个价格的最小值和最大值,您可以使用以下内容:

SELECT  mt.Type2,
        mt.Type,
        mt.Price,
        t.ID,
        t.Name
FROM    (   SELECT  Type, MIN(Price) AS Price, 'MIN' AS Type2
            FROM    NormalT
            GROUP BY Type
            UNION ALL
            SELECT  Type, MAX(Price) AS Price, 'MAX' AS Type2
            FROM    NormalT
            GROUP BY Type
        ) mt
        INNER JOIN NormalT T
            ON mt.Type = T.Type
            AND mt.Price = t.Price
ORDER BY mt.Type2, mt.Type, t.ID;
SELECT  mt.Type2,
        t.Type,
        mt.Price,
        t.ID,
        t.Name
FROM    (   SELECT  MIN(Price) AS Price, 'MIN' AS Type2
            FROM    NormalT
            UNION ALL
            SELECT  MAX(Price) AS Price, 'MAX' AS Type2
            FROM    NormalT
        ) mt
        INNER JOIN NormalT T
            ON mt.Price = t.Price;
将从示例数据中输出以下内容:

TYPE2   TYPE        PRICE   ID  NAME
MAX     Price_a     250     1   Chips Ahoy
MAX     Price_a     250     2   Chocolate Chunk
MAX     Price_b     530     1   Chips Ahoy
MAX     Price_c     720     1   Chips Ahoy
MAX     Price_d     850     3   Oreo
MIN     Price_a     103     3   Oreo
MIN     Price_b     44.52   3   Oreo
MIN     Price_c     32.92   2   Chocolate Chunk
MIN     Price_d     110     2   Chocolate Chunk
但是,如果它只是所有价格(a、b、c和d)的最小值和最大值,则可以使用:

SELECT  mt.Type2,
        mt.Type,
        mt.Price,
        t.ID,
        t.Name
FROM    (   SELECT  Type, MIN(Price) AS Price, 'MIN' AS Type2
            FROM    NormalT
            GROUP BY Type
            UNION ALL
            SELECT  Type, MAX(Price) AS Price, 'MAX' AS Type2
            FROM    NormalT
            GROUP BY Type
        ) mt
        INNER JOIN NormalT T
            ON mt.Type = T.Type
            AND mt.Price = t.Price
ORDER BY mt.Type2, mt.Type, t.ID;
SELECT  mt.Type2,
        t.Type,
        mt.Price,
        t.ID,
        t.Name
FROM    (   SELECT  MIN(Price) AS Price, 'MIN' AS Type2
            FROM    NormalT
            UNION ALL
            SELECT  MAX(Price) AS Price, 'MAX' AS Type2
            FROM    NormalT
        ) mt
        INNER JOIN NormalT T
            ON mt.Price = t.Price;
将输出以下内容:

TYPE2   TYPE    PRICE       ID  NAME
MIN     Price_c     32.92   2   Chocolate Chunk
MAX     Price_d     850     3   Oreo

试试这个,它在模拟分析,因为MYSQL默认情况下没有这些分析:

SELECT id, 
             ( select MAX(price_a) from $t t2 where  t2.id = t1.id ) AS price_a, 
             ( select MAX(price_b) from $t t2 where  t2.id = t1.id ) AS price_b, 
             ( select MAX(price_c) from $t t2 where  t2.id = t1.id ) AS price_c, 
             ( select MAX(price_d) from $t t2 where  t2.id = t1.id ) AS price_d 
             FROM $t t1 WHERE id IN(". implode(',', array_map('intval', $arrIds)) .")

来源:

试试这个,它是在模拟分析,因为MYSQL默认没有这些分析:

SELECT id, 
             ( select MAX(price_a) from $t t2 where  t2.id = t1.id ) AS price_a, 
             ( select MAX(price_b) from $t t2 where  t2.id = t1.id ) AS price_b, 
             ( select MAX(price_c) from $t t2 where  t2.id = t1.id ) AS price_c, 
             ( select MAX(price_d) from $t t2 where  t2.id = t1.id ) AS price_d 
             FROM $t t1 WHERE id IN(". implode(',', array_map('intval', $arrIds)) .")

来源:

为了安全起见:您希望有两条结果记录;给定您的示例数据和一个包含所有三项的查询(即不包含WHERE子句):min=(id:2,price\u c:32.92)和max=(id:3,price\u d:850)?是的,我知道。我可以在以后限制它们或对结果重新排序。您希望的输出是什么?具体来说,如果最高价格为250,并且有两种产品的最高价格为250,您对最高价格的期望是什么?如果速度很重要,请规范化您的数据。哦,价格类别是十进制的(10,2)?提醒我不要吃你的奥利奥!为了安全起见:您希望有两个结果记录;给定您的示例数据和一个包含所有三项的查询(即不包含WHERE子句):min=(id:2,price\u c:32.92)和max=(id:3,price\u d:850)?是的,我知道。我可以在以后限制它们或对结果重新排序。您希望的输出是什么?具体来说,如果最高价格为250,并且有两种产品的最高价格为250,您对最高价格的期望是什么?如果速度很重要,请规范化您的数据。哦,价格类别是十进制的(10,2)?提醒我不要吃你的奥利奥!非常感谢。这不可能在一个查询中实现吗?不,不可能。这是因为MAX、MIN、AVG和all都返回一条记录。不是多重的。出于您的原因,您将需要多个ID,每个区域的最高和最低价格。那是不可能的,谢谢。这不可能在一个查询中实现吗?不,不可能。这是因为MAX、MIN、AVG和all都返回一条记录。不是多重的。出于您的原因,您将需要多个ID,每个区域的最高和最低价格。这是不可能的。