SQLite Group concat
W Sqlite mogę użyć group_concat do zrobienia:
1...A
1...B
1...C
2...A
2...B
2...C
1...C,B,A
2...C,B,A
Ale kolejność konkatenacji jest przypadkowa-według docs.
Muszę sortować wyjście group_concat aby było
1...A,B,C
2...A,B,C
Jak mogę to zrobić? 2 answers
Czy nie można użyć elementu podrzędnego z klauzulą order by, a następnie pogrupować wartości concat?
Coś jak
SELECT ID, GROUP_CONCAT(Val)
FROM (
SELECT ID, Val
FROM YourTable
ORDER BY ID, Val
)
GROUP BY ID;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-24 08:56:09
Aby być bardziej precyzyjnym, zgodnie z docs :
Kolejność konkatenowanych elementów jest dowolna.
To tak naprawdę nie znaczy losowe, to po prostu oznacza, że deweloperzy zastrzegają sobie prawo do korzystania z dowolnego zamówienia, które piszczą, nawet różne dla różnych zapytań lub w różnych wersjach SQLite.
W obecnej wersji, kolejność ta może być tą sugerowaną przez odpowiedź Adriana Standera, ponieważ jego kod wydaje się działać. Więc możesz po prostu strzeż się testów jednostkowych i skończ z tym. Ale bez zbadania kodu źródłowego SQLite naprawdę dokładnie nigdy nie można być 100% pewien, że to zawsze będzie działać.
Jeśli chcesz zbudować SQLite ze źródła, Możesz również spróbować napisać własną zdefiniowaną przez użytkownika funkcję agregacyjną , ale jest łatwiejszy sposób.
Na szczęście, od wersji 3.25.0, masz funkcje okien , zapewniające gwarancję pracy, choć nieco brzydkie rozwiązanie dla Twojego problem.
Jak widać w dokumentacji, funkcje systemu windows mają swoje własne klauzule ORDER BY
:
W powyższym przykładzie ramka okna składa się ze wszystkich wierszy pomiędzy poprzednim wierszem ("1 poprzedzający") i następnym wierszem ("1 następny"), włącznie, gdzie wiersze są sortowane zgodnie z klauzulą ORDER BY w window-defn (w tym przypadku "ORDER BY a").
Zauważ, że samo to nie musi oznaczać, że wszystkie funkcje zbiorcze respektują porządek wewnątrz ramki okna, ale jeśli spojrzysz na testy jednostkowe , zobaczysz, że tak naprawdę jest:
do_execsql_test 4.10.1 {
SELECT a,
count() OVER (ORDER BY a DESC),
group_concat(a, '.') OVER (ORDER BY a DESC)
FROM t2 ORDER BY a DESC
} {
6 1 6
5 2 6.5
4 3 6.5.4
3 4 6.5.4.3
2 5 6.5.4.3.2
1 6 6.5.4.3.2.1
0 7 6.5.4.3.2.1.0
}
Więc podsumowując, możesz napisać
SELECT ID, GROUP_CONCAT(Val) OVER (PARTITION BY ID ORDER BY Val) FROM YourTable;
W wyniku:
1|A
1|A,B
1|A,B,C
2|A
2|A,B
2|A,B,C
Który niestety zawiera również każdy prefiks pożądanych agregacji. Zamiast tego chcesz określić ramki okien, aby zawsze zawierały pełny zakres, a następnie odrzucić nadmiarowe wartości, jak to:
SELECT DISTINCT ID, GROUP_CONCAT(Val)
OVER (PARTITION BY ID ORDER BY Val ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
FROM YourTable;
Lub w ten sposób:
SELECT * FROM (
SELECT ID, GROUP_CONCAT(Val)
OVER (PARTITION BY ID ORDER BY Val ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
FROM YourTable
)
GROUP BY ID;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-17 13:09:29