2

我有一个表,我的表结构是这样的:

unique_id     vendor_name      price1     price2     price3    code 

1             Vendor 1         0.0012     0.0014     0.0054     125
2             Vendor 2         0.0015     0.0016     0.0050     125
3             Vendor 3         0.0011     0.0019     0.0088     125
4             Vendor 1         0.0025     0.0024     0.0034     126
5             Vendor 2         0.0043     0.0019     0.0065     126
6             Vendor 3         0.0019     0.0085     0.0082     126        

我必须按代码获取每个价格列组的最低价格。我的预期输出如下:

Code          price1          price2      price3     vendor for price1      vendor for price 2      vendor for price 3

125           0.0011          0.0014      0.0050     Vendor3                Vendor1                 Vendor 2 
126           0.0019          0.0019      0.0034     Vendor3                Vendor2                 Vendor 1

那么获取这样的记录的 MySQL 查询是什么?而且我还必须进行查询以从表中获取最大值和第二高值,并且可能有任意数量的带有单个代码的行。

我的数据在这个SQL Fiddle中。

在第二高值的情况下,输出应为:

Code          price1          price2      price3     vendor for price1      vendor for price 2      vendor for price 3
125           0.0012          0.0016      0.0054     Vendor1                Vendor2                 Vendor 1 
126           0.0025          0.0024      0.0065     Vendor1                Vendor1                 Vendor 2
4

4 回答 4

2

这是你如何做到的

SELECT
  vender_prices.code,
  l.price1,
  r.price2,
  m.price3,
  l.vendor_name `Vender1`,
  r.vendor_name `Vender2`,
  m.vendor_name `Vender3`
FROM vender_prices
  LEFT JOIN (SELECT
               code, vendor_name, vender_prices.price1
             FROM vender_prices
               INNER JOIN (SELECT MIN(price1) AS price1 FROM vender_prices GROUP BY vender_prices.code) AS l
                 ON l.price1 = vender_prices.price1
             GROUP BY vender_prices.code
             ) as l ON vender_prices.code = l.code
  LEFT JOIN (SELECT
               code, vendor_name, vender_prices.price2
             FROM vender_prices
               INNER JOIN (SELECT MIN(price2) AS price2 FROM vender_prices GROUP BY vender_prices.code) AS l
                 ON l.price2 = vender_prices.price2
             GROUP BY vender_prices.code
             ) as r ON vender_prices.code = r.code
  LEFT JOIN (SELECT
               code, vendor_name, vender_prices.price3
             FROM vender_prices
               INNER JOIN (SELECT MIN(price3) AS price3 FROM vender_prices GROUP BY vender_prices.code) AS l
                 ON l.price3 = vender_prices.price3
             GROUP BY vender_prices.code
             ) as m ON vender_prices.code = m.code
GROUP BY vender_prices.code

SQL 小提琴演示

输出

| CODE | PRICE1 | PRICE2 | PRICE3 |  VENDER1 |  VENDER2 |  VENDER3 |
--------------------------------------------------------------------
|  125 | 0.0011 | 0.0014 | 0.0050 | Vendor 3 | Vendor 1 | Vendor 2 |
|  126 | 0.0019 | 0.0019 | 0.0034 | Vendor 3 | Vendor 2 | Vendor 1 |
于 2013-04-25T11:23:54.660 回答
1
SELECT
    data.*,
    v1.vendor_name 'vendor for price1',
    v2.vendor_name 'vendor for price2',
    v3.vendor_name 'vendor for price3'
FROM
    (
        SELECT
            Code,
            MIN(price1) price1,
            MIN(price2) price2,
            MIN(price3) price3
        FROM
            tbl
        GROUP BY Code
    ) data
    LEFT JOIN
    (
        SELECT 
            MIN(vendor_name) vendor_name,
            Code
        FROM
            tbl
        WHERE
            price1 = 
            (
                SELECT
                    MIN(price1)
                FROM
                    tbl t
                WHERE
                    t.Code = tbl.Code
            )
        GROUP BY Code
    ) v1 ON data.Code = v1.Code
    LEFT JOIN
    (
        SELECT 
            MIN(vendor_name) vendor_name
            Code
        FROM
            tbl
        WHERE
            price2 = 
            (
                SELECT
                    MIN(price2)
                FROM
                    tbl t
                WHERE
                    t.Code = tbl.Code
            )
        GROUP BY Code
    ) v2 ON data.Code = v2.Code
    LEFT JOIN
    (
        SELECT 
            MIN(vendor_name) vendor_name
            Code
        FROM
            tbl
        WHERE
            price3 = 
            (
                SELECT
                    MIN(price3)
                FROM
                    tbl t
                WHERE
                    t.Code = tbl.Code
            )
        GROUP BY Code
    ) v3 ON data.Code = v3.Code

尽管查询本身看起来很大,但连接重复了 3 次。

更新我更新了查询删除LIMIT和添加MIN(vendor_name) vendor_name而不是vendor_name.

演示

这里

输出

| CODE | PRICE1 | PRICE2 | PRICE3 | VENDOR FOR PRICE1 | VENDOR FOR PRICE2 | VENDOR FOR PRICE3 |
-----------------------------------------------------------------------------------------------
|  125 | 0.0011 | 0.0014 | 0.0050 |          Vendor 3 |          Vendor 1 |          Vendor 2 |
|  126 | 0.0019 | 0.0019 | 0.0034 |          Vendor 3 |          Vendor 2 |          Vendor 1 |
于 2013-04-25T10:17:07.693 回答
0

这是一个很好的做法,我先尝试一种蛮力方法@。

select 1 as wh,code,min(price1) as price,vendor_name
from(
  select code,price1,vendor_name
  from ForgeRock
  order by code,price1
  )t1
group by code
union all
select 2 as wh,code,min(price2) as price,vendor_name
from(
  select code,price2,vendor_name
  from ForgeRock
  order by code,price2
  )t1
group by code
union all
select 3 as wh,code,min(price3) as price,vendor_name
from(
  select code,price3,vendor_name
  from ForgeRock
  order by code,price3
  )t1
group by code

这是一个非常简单易行的方法,不用join,我觉得用起来就够了。我添加了一个列 wh,如果需要,您可以旋转结果。但是,您不能使用上面的代码获得第二低的结果。有几种方法可以达到这个目标,我建议你尝试制作这样的分区:

CREATE TABLE ForgeRock
    (`unique_id` tinyint, `vendor_name` varchar(8), `price1` float(5,4)
    , `price2` float(5,4), `price3` float(5,4),`code` tinyint)
PARTITION BY KEY(code)
PARTITIONS 2;

INSERT INTO ForgeRock
    (`unique_id`, `vendor_name`, `price1`, `price2`, `price3`, `code`)
VALUES
(1,'Vendor 1',0.0012,0.0014,0.0054,125),
(2,'Vendor 2',0.0015,0.0016,0.0050,125),
(3,'Vendor 3',0.0011,0.0019,0.0088,125),
(4,'Vendor 1',0.0025,0.0024,0.0034,126),
(5,'Vendor 2',0.0043,0.0019,0.0065,126),
(6,'Vendor 3',0.0019,0.0085,0.0082,126);

嗯,这有点棘手,但是当你没有这么多不同的值时非常有用code。你可以得到这样的结果:

select * from
(select code,price1 as price,vendor_name
from ForgeRock partition (p0)
order by price1
Limit 1,1
)t1
union all
select * from
(select code,price1 as price,vendor_name
from ForgeRock partition (p1)
order by price1
Limit 1,1
)t1
union all
select * from
(select code,price2 as price,vendor_name
from ForgeRock partition (p0)
order by price2
Limit 1,1
)t1
union all
select * from
(select code,price2 as price,vendor_name
from ForgeRock partition (p1)
order by price2
Limit 1,1
)t1
union all
select * from
(select code,price3 as price,vendor_name
from ForgeRock partition (p0)
order by price3
Limit 1,1
)t1
union all
select * from
(select code,price3 as price,vendor_name
from ForgeRock partition (p1)
order by price3
Limit 1,1
)t1

虽然我认为您可以明显改善我的答案,但我会将这份工作留给您。

于 2016-08-02T07:51:17.693 回答
0

尝试这个 :

select table1.vendor_name as vendor_name_for_price1,table2.vendor_name as vendor_name_for_price2, table3.vendor_name as vendor_name_for_price3

from 
table table1, table table2, table table3,
(Select code, min(price1),min(price2),min(price3) from table group by code ) TMP1

where
table1.price1=min(price1) and table1.code=TMP1.code
and
table2.price2=min(price2) and table2.code=TMP2.code
and
table3.price3=min(price3) and table3.code=TMP2.code ;
于 2016-08-01T22:04:28.303 回答