Mit rekursiven Abfragen kann man auch die eine oder andere Sache machen, die auf den ersten Blick vielleicht ein wenig schräg erscheint:
test=# \set radius 1.0
test=# \set colours '''#;o:X"@+-=123456789abcdef'''
test=# \set width 50
test=# \set height 25
test=# WITH slices AS (
SELECT CAST(row_number() over () AS integer) AS slice,
name,
value,
100.0 * value / sum(value) OVER () AS percentage,
2*PI() * sum(value) OVER (rows unbounded preceding)
/ sum(value) OVER () AS radians
FROM (VALUES ('red',1),
('blue',2),
('orange',3),
('white',4)
) AS DATA(name,value))
(
SELECT array_to_string(array_agg(c),'') AS pie_chart
FROM (
SELECT x, y,
CASE WHEN NOT (sqrt(pow(x, 2) + pow(y, 2))
BETWEEN :radius*1/10 AND :radius)
THEN ' '
ELSE substring(:colours,
(SELECT min(slice)
FROM slices
WHERE radians >= PI() + atan2(y,-x)),
1)
END AS c
FROM (SELECT 2.0*generate_series(0,:width)/:width-1.0) AS x(x),
(SELECT 2.0*generate_series(0,:height)/:height-1.0) AS y(y)
ORDER BY y,x
) AS xy
GROUP BY y
ORDER BY y
)
UNION ALL
SELECT repeat(substring(:colours,slice,1), 2) || ' ' ||
name || ': ' ||
value || ' (' || round(percentage,0) || '%)'
FROM slices;
Das Ergebnis ist ein kleiner ASCII-Art Pie Chart:
pie_chart
-----------------------------------------------------
;
oo;;;;;;;;;;;;;;;;;
ooooooo;;;;;;;;;;;;;;;;;;;;
oooooooooo;;;;;;;;;;;;;;;;;;;;;;;
ooooooooooooo;;;;;;;;;;;;;;;;;;;;;;;;
oooooooooooooooo;;;;;;;;;;;;;;;;;;;;;;;;;
ooooooooooooooooo;;;;;;;;;;;;;;;;;;;;;;####
ooooooooooooooooooo;;;;;;;;;;;;;;;;;;;#######
ooooooooooooooooooooo;;;;;;;;;;;;;;;###########
oooooooooooooooooooooo;;;;;;;;;;;;###############
ooooooooooooooooooooooo;;;;;;;;##################
oooooooooooooooooooooooo;;;;;####################
oooooooooooooooooooooo ######################
oooooooooooooooooooooo ::::::::::::::::::::::
oooooooooooooooooooo:::::::::::::::::::::::::::::
oooooooooooooooooo:::::::::::::::::::::::::::::::
ooooooooooooooo::::::::::::::::::::::::::::::::::
ooooooooooo::::::::::::::::::::::::::::::::::::
ooooooo::::::::::::::::::::::::::::::::::::::
oooo:::::::::::::::::::::::::::::::::::::::
:::::::::::::::::::::::::::::::::::::::::
:::::::::::::::::::::::::::::::::::::
:::::::::::::::::::::::::::::::::
:::::::::::::::::::::::::::
:::::::::::::::::::
:
## red: 1 (10%)
;; blue: 2 (20%)
oo orange: 3 (30%)
:: white: 4 (40%)
(30 rows)
Wir wollen an dieser Stelle gar nicht näher auf die Mathematik hinter diesem Beispiel eingehen sondern einfach feststellen, dass mit WITH RECURSIVE auch komplexe Aufgaben lösbar sind - auch wenn der Code in vielen Fällen durchaus kompliziert werden kann.