Open pigreco opened 2 years ago
@pigreco scrivo senza fare test.
Ma non puoi fare due left join tra l'output di
SELECT
nome,
max(lg) AS lg_max,
max(ln) AS ln_max
FROM
dataset
GROUP BY
1
e la tabella di input? Prima per nome e valore lg e poi per nome e valore ln e ti prendi l'ID?
Ma non puoi fare due left join
è quello che sto facendo, ma se ci fossero due valori max uguali (esempio pk_uid 6 e 8 per il campo ln
) li prenderebbe entrambi
ecco esempio:
SELECT pk_uid, t.nome
FROM
(
SELECT
nome,
max(lg) AS lg_max,
max(ln) AS ln_max
FROM
dataset_test
GROUP BY
1
) t
LEFT JOIN
dataset_test
ON ln_max = ln
@pigreco una piccola correzione: il JOIN con doppia condizione, può essere semplice JOIN e non LEFT
Una piccola nota carina di uso di Miller.
Se arrivi all'output SQL di base
NOME,lg_max,ln_max,IDLG,IDLN
4791,47.900000,41.900000,0,4
7307,45.000000,38.400000,16,6
7307,45.000000,38.400000,16,8
7724,58.100000,49.500000,17,17
e vuoi unire in due record 7307, avendo un cella con i due valor di IDLN, puoi lanciare
mlr --csv reshape -r "ID" -o i,v then \ 130 ↵
filter -x '$v==""' then \
uniq -a then \
nest --ivar ";" -f v then \
reshape -s i,v then \
unsparsify input.csv
e avere
NOME | lg_max | ln_max | IDLG | IDLN |
---|---|---|---|---|
4791 | 47.900000 | 41.900000 | 0 | 4 |
7307 | 45.000000 | 38.400000 | 16 | 6;8 |
7724 | 58.100000 | 49.500000 | 17 | 17 |
Il passaggio fondamentale è passare da wide a long con reshape -r "ID" -o i,v
NOME | lg_max | ln_max | i | v |
---|---|---|---|---|
4791 | 47.900000 | 41.900000 | IDLG | 0 |
4791 | 47.900000 | 41.900000 | IDLN | 4 |
7307 | 45.000000 | 38.400000 | IDLG | 16 |
7307 | 45.000000 | 38.400000 | IDLN | 6 |
7307 | 45.000000 | 38.400000 | IDLG | 16 |
7307 | 45.000000 | 38.400000 | IDLN | 8 |
7724 | 58.100000 | 49.500000 | IDLG | 17 |
7724 | 58.100000 | 49.500000 | IDLN | 17 |
Poi rimuovo eventuali valori di v
nulli, rimuovo righe duplicate, poi implodo le righe in cui a parità di altri campi hanno lo stesso valore di v
e poi in ultimo di nuovo da long a wide.
Una soluzione al quesito:
WITH calcolo_max AS (
SELECT
NOME,
max(lg) AS lg_max,
max(ln) AS ln_max
FROM
dataset_test
GROUP BY
NOME
)
SELECT
calcolo_maxdue.NOME,
id_lg_max,
lg_max,
PK_UID AS id_ln_max,
ln_max
FROM
(
SELECT
calcolo_max.NOME,
lg_max,
ln_max,
PK_UID AS id_lg_max
FROM
calcolo_max
JOIN dataset_test f ON calcolo_max.NOME = f.NOME
AND calcolo_max.lg_max = f.LG
) calcolo_maxdue
JOIN dataset_test f ON calcolo_maxdue.NOME = f.NOME
AND calcolo_maxdue.ln_max = f.LN
Aggiungo screenshot per la ricetta:
ricetta fatta e pubblicata
https://tansignari.opendatasicilia.it/ricette/query/id_valori_max/
riapro perché nel caso in cui esistano due punti diversi con stessi valori di lg e ln, la query fa il prodotto cartesiano
non sono sicuro di avere capito tutto, ma non puoi fare un distinct alla fine?
non sono sicuro di avere capito tutto, ma non puoi fare un distinct alla fine?
ho riaperto per tenerne traccia appena posso faccio alcuni test
questa query mi aiuta molto nel ragionamento
SELECT
pk_uid,
nome,
max_lg,
max_ln
FROM
(
SELECT
a.pk_uid,
a.nome,
a.lg,
a.ln,
lg_max,
ln_max,
a.lg = lg_max AS max_lg,
a.ln = ln_max AS max_ln
FROM
dataset_test a
LEFT JOIN (
SELECT
NOME,
max(lg) AS lg_max,
max(ln) AS ln_max
FROM
dataset_test
GROUP BY
NOME
) USING (NOME)
) k
WHERE
max_lg | | max_ln != 0 | | 0
ORDER BY
nome
dove:
1
è vero0
è falsoovvero: calcola i valori massimi LG e LN, poi nella stessa tabella di INPUT aggiungo due campi popolandoli con il confronto tra il valore massimo dell'aggregazione e i vari record, dove l'uguaglianza è vera metterà 1 altrimenti 0.
In QGIS e con le espressioni, il tutto sarebbe:
maximun("lg","nome")= "lg"
e maximun("ln","nome")= "ln"
Ho un insieme di dati caratterizzati da un id univoco (
pk_uid
) e devo determinare il valore massimo, raggruppando secondo l'attributo (nome
), di due altri attributilg
eln
: come determinare l'ID (pk_uid) corrispondente ai valori massimi risultanti?qui un esempio del dataset:
La seguente query determina i valori massimi aggregati per
nome
degli attributilg
eln
che restituisce:
a me interessa capire come scrivere una query che restituisca questo:
dove:
id_lg_max
è l'id del valore massimo dell'attributolg
id_ln_max
è l'id del valore massimo dell'attributoln
Un modo sarebbe quello di utilizzare le espressioni dentro la funzione max, ecco un esempio:
otterrei la tabella sotto, che risulta confusionaria: