2016-12-02 115 views
1

我有一个产品和价格表。它包含10个不同的价格列。我能够成功找到所有10个价格栏中的最低价值。如何显示SQL找到最小值的列的名称?

所以,从这个数据:

Prod. Name | Week1 | Week2 | Week N | Week 10 
Pizza  | $1.29 | $1.29 | $1.42 | $1.01 

而且我可以显示:

Prod. Name | Lowest Price 
Pizza  | $1.01 

但我怎么还可以添加另一列显示的列/ s的从最低值来了?

理想的输出将如下所示:

Prod. Name | Lowest Price | From Week 
Pizza  | $1.01  | 10 

我使用的显示输出的搜索查询是:

SELECT ProdName, LEAST(d1, d2, d3, d4, d5, d6, d7, d8, d9, d10) FROM results;

编辑: 我忘了提,我正在处理大约1,600行数据。这当然会使编码变得更复杂一些!

回答

0

你可以比较,不仅简单的值,而且还记录:如果没有足够的

with t(x,y,z) as (values(1,3,2),(5,2,3)) 
select *, least((x,'x'::text),(y,'y'::text),(z,'z'::text)) from t; 
 
╔═══╤═══╤═══╤═══════╗ 
║ x │ y │ z │ least ║ 
╠═══╪═══╪═══╪═══════╣ 
║ 1 │ 3 │ 2 │ (1,x) ║ 
║ 5 │ 2 │ 3 │ (2,y) ║ 
╚═══╧═══╧═══╧═══════╝ 

然后你可以将其转换为jsonb例如和retrive值在不同的行:

with t(x,y,z) as (values(1,3,2),(5,2,3)) 
select *, j->>'f1' as val, j->>'f2' as fld 
from t, to_jsonb(least((x,'x'::text),(y,'y'::text),(z,'z'::text))) as j; 
 
╔═══╤═══╤═══╤══════════════════════╤═════╤═════╗ 
║ x │ y │ z │   j   │ val │ fld ║ 
╠═══╪═══╪═══╪══════════════════════╪═════╪═════╣ 
║ 1 │ 3 │ 2 │ {"f1": 1, "f2": "x"} │ 1 │ x ║ 
║ 5 │ 2 │ 3 │ {"f1": 2, "f2": "y"} │ 2 │ y ║ 
╚═══╧═══╧═══╧══════════════════════╧═════╧═════╝ 

并为您的数据可能是:

select ProdName, j->>'f1' as val, j->>'f2' as fld 
from results, to_jsonb(least((d1,'d1'),(d2,'d2'),(d3,'d3'),...,(d10,'d10'))); 
0

对于这个答案,我创建5种价格

create temp table p (id text, p1 float, p2 float, p3 float, p4 float, p5 float); 
insert into p values ('Pizza', 1.4, 2, 1.3, 2.1, 1.6); 
insert into p values ('Tea', 1.4, 3, 3, 2.1, 1.6); 

首先UNPIVOT然后表的表作为一个数组,为期一周的名称和每周的价格。

select 
    id, 
    unnest(array['week1','week2','week3','week4','week5']), 
    unnest(array[p1,p2,p3,p4,p5]) 
from p 

+-------+--------+--------+ 
| id | unnest | unnest | 
+-------+--------+--------+ 
| Pizza | week1 | 1,4 | 
+-------+--------+--------+ 
| Pizza | week2 | 2 | 
+-------+--------+--------+ 
| Pizza | week3 | 1,3 | 
+-------+--------+--------+ 
| Pizza | week4 | 2,1 | 
+-------+--------+--------+ 
| Pizza | week5 | 1,6 | 
+-------+--------+--------+ 
| Tea | week1 | 1,4 | 
+-------+--------+--------+ 
| Tea | week2 | 3 | 
+-------+--------+--------+ 
| Tea | week3 | 3 | 
+-------+--------+--------+ 
| Tea | week4 | 2,1 | 
+-------+--------+--------+ 
| Tea | week5 | 1,6 | 
+-------+--------+--------+ 

然后过滤此表结果的最低价格。

where cte.price = (select least(p1,p2,p3,p4,p5) from p where p.id = cte.id); 

您可以点击此处查看:http://rextester.com/VKXK37428

with cte (id, week, price) as 
(
select 
    id, 
    unnest(array['week1','week2','week3','week4','week5']), 
    unnest(array[p1,p2,p3,p4,p5]) 
from p 
) 
select id, week, price 
from cte 
where cte.price = (select least(p1,p2,p3,p4,p5) from p where p.id = cte.id); 

这是结果:

+-------+-------+-------+ 
| id | week | price | 
+-------+-------+-------+ 
| Pizza | week3 | 1,3 | 
+-------+-------+-------+ 
| Tea | week1 | 1,4 | 
+-------+-------+-------+ 
+0

喜。更新与另一行和分组? '插入p值('茶',1.9,2,1.3,0.3,1。6);'我有一种感觉,这个问题不是关于唯一的行 –

+0

让我编辑答案 – McNets

+0

你可以再次检查 – McNets

0

深夜。似乎像一个车轮,但无论如何 - 使用JSON的方式做到这一点:

a=# select * from results ; 
i | e | f | Prod .Name 
---+---+---+------------ 
2 | 1 | 3 | Pizza 
2 | 3 | 4 | Beer 
(2 rows) 

a=# select "Prod. Name","Lowest Price","From Week" from (
with p as (select "Prod .Name" as n,row_to_json(results) p from results) 
select 
    p.n as "Prod. Name" 
, min(case when j.value::text != concat('"',p.n,'"') then j.value::text::float end) over(partition by p.n) "Lowest Price" 
, case when j.value::text != concat('"',p.n,'"') then j.value::text::float end compare 
, j.key::text "From Week" 
from p, json_each(p.p) as j 
) s 
where compare = "Lowest Price" 
; 
Prod. Name | Lowest Price | From Week 
------------+--------------+----------- 
Beer  |   2 | i 
Pizza  |   1 | e 
(2 rows)