2016-12-02 93 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)