假设我有一张桌子。
当附加位于不同行中的值时,我遇到以下问题。
rankk val price
1 A 10
2 B 20
3 C 30
如何获得此结果?
rank val2
1 A
2 A,B
3 A,B,C
我坚持下去
rank val2
1 A
2 ,B
3 ,C
create multiset volatile table tmp_db (
rankk integer,
val varchar(1),
price integer)
primary index (val) on commit preserve rows;
insert into tmp_db values (1,'A',10);
insert into tmp_db values (2,'B',20);
insert into tmp_db values (3,'C',30);
sel rankk,
max(case when rankk = 1 then val else '' end) ||
max(case when rankk = 2 then ',' || val else '' end) ||
max(case when rankk = 3 then ',' || val else '' end) as val2,
avg(price) as avg_price
from tmp_db
group by 1;
不便之处,敬请原谅。
答案 0 :(得分:1)
您需要这样的自联接
SEL t1.rankk,
Max(CASE WHEN t2.rankk = 1 THEN t2.val ELSE '' end) ||
Max(CASE WHEN t2.rankk = 2 THEN ',' || t2.val ELSE '' end) ||
Max(CASE WHEN t2.rankk = 3 THEN ',' || t2.val ELSE '' end) AS val2,
Avg(t2.price) AS avg_price
FROM tmp_db AS t1 JOIN tmp_db AS t2
ON t1.rankk >= t2.rankk -- include all previous rows
GROUP BY 1;
也可以使用更高级别的xmlagg
(这将在值之间添加一个空格):
SELECT t1.rankk,
Trim(Trailing ',' FROM
(XmlAgg(Trim(t2.val)|| ',' ORDER BY t2.val DESC) (VARCHAR(1000)))) AS val,
Avg(t2.price) AS avg_price
FROM tmp_db AS t1 JOIN tmp_db AS t2
ON t1.rankk >= t2.rankk
GROUP BY 1
根据您的实际数据,您还可以使用递归:
WITH RECURSIVE cte AS
(
SELECT rankk, val, Cast(val AS VARCHAR(1000)) AS rslt, price
FROM tmp_db
WHERE rankk = 1 -- start with 1st rank
UNION ALL
SELECT t.rankk, t.val,
cte.rslt || ',' || t.val AS rslt,
cte.price + t.price -- to calculate average using sum/rankk
FROM tmp_db AS t JOIN cte
ON t.rankk = cte.rankk+1
)
SELECT rankk, rslt, price / rankk
FROM cte
答案 1 :(得分:1)
尝试使用递归cte
# for python 2.7
import string
import win32api
def getfreedriveletter():
""" Find first free drive letter """
assigneddrives = win32api.GetLogicalDriveStrings().split('\000')[:-1]
assigneddrives = [item.rstrip(':\\').lower() for item in assigneddrives]
for driveletter in list(string.ascii_lowercase[2:]):
if not driveletter in assigneddrives:
return driveletter.upper() + ':'