podwójna konkatenacja

Użytkowanie programu bazodanowego
Awatar użytkownika
czp
Posty: 47
Rejestracja: czw mar 04, 2010 5:38 pm

podwójna konkatenacja

Post autor: czp »

Witam .

Chcę połączyć w prostej tabeli sąsiednie pola `data` i `obieg` a następnie uzyskane w ten sposób dane połączyć ponownie w tej samej kolumnie ale tylko pól które mają ten sam numer `id_rs` . Pojedyncza konkatenacja to nie problem, ale co do drugiego łączenia to zupełnie nie wiem jak do tego podejść.

Jako załączniki przedstawiam prosty plik base z tym problemem oraz plik pdf z podana tabelką bazy i efektem jaki chcę uzyskać.

No pdf zablokowane to dołączam w pliku writera
Załączniki
opis.odt
(17.6 KiB) Pobrany 189 razy
konkatenacja.odb
(4.55 KiB) Pobrany 168 razy
Ostatnio zmieniony śr kwie 14, 2010 1:34 pm przez czp, łącznie zmieniany 1 raz.
Windows 7 i openoffice 3.2
Jan_J
Posty: 4558
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: podwójna konkatenacja

Post autor: Jan_J »

Ja bym szedł w kierunku grupowania po kluczu i funkcji łączącej ciąg tekstów w jeden tekst (podobnie jak robi się zliczanie czy sumowanie w grupach).
Takiej funkcji nie ma w standardzie, trzeba by ją sobie napisać, a to w każdej bazie robi się inaczej.

Niektóre systemy baz danych taką funkcję mogą mieć od razu. Inne, np. MS SQL, mają rozszerzenia składniowe, które pozwalają na coś podobnego.

W niektórych ,,obiektowych'' bazach, np. w postgresie, można by spytać

Kod: Zaznacz cały

SELECT "id_rs", 
        (select data || ':' || obieg || '\n' from "dane" as "d2" where "d1"."id_rs" = "d2"."id_rs") as "data_obieg"
FROM "dane" as "d1"
GROUP BY "id_rs"
ORDER BY "id_rs" ASC
Otrzymamy prawie to, o co Ci chodzi; obróbka końcowa poza środowiskiem bazy jest już prosta.

A w Base? nie wiem...
JJ
LO (7.6|24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
Awatar użytkownika
czp
Posty: 47
Rejestracja: czw mar 04, 2010 5:38 pm

Re: podwójna konkatenacja

Post autor: czp »

Dzięki

sprawdzam - base tylko dla przykładu a bazę mam w mysql.
Windows 7 i openoffice 3.2
mg2
Posty: 170
Rejestracja: czw sty 28, 2010 9:20 pm

Re: podwójna konkatenacja

Post autor: mg2 »

Można przepuścić tabelę przez makro zamieniające wiersze z kolumnami. (Calc ma taką funkcję).
OOo3.1.1 na Ubuntu 9.04
Awatar użytkownika
czp
Posty: 47
Rejestracja: czw mar 04, 2010 5:38 pm

Re: podwójna konkatenacja

Post autor: czp »

Na razie - zostawiam makra i chce tego dokonać na poziomie MySQL.
Męczę się na przykładem podanym przez Jan_J - nie działa mi bo w MySQL operatorem konkatenacji będzie CONCAT i nie można wprost połączyć pola daty i pola tekstowego - należy więc chyba dokonać konwersji pola daty do pola tekstowego i dopiero je połączyć a więc operator CONCAT_WS.
Jestem tu na dobrej drodze i tą pierwszą konkatenacje chyba zrobię.
Windows 7 i openoffice 3.2
mg2
Posty: 170
Rejestracja: czw sty 28, 2010 9:20 pm

Re: podwójna konkatenacja

Post autor: mg2 »

Szukaj w sieci "mysql pivot"
http://en.wikibooks.org/wiki/MySQL/Pivot_table

Jeżeli liczba powtórzeń jest jednakowa to sprawa jest w miarę prosta. W przykładzie, który załączyłeś każda osoba powtarza się dokładnie trzy razy.

Jeżeli chodzi o CONCAT w MySQL to tu jest przykład pokazujący, że można łączyć różne typy
http://www.tutorialspoint.com/mysql/mys ... nction.htm
OOo3.1.1 na Ubuntu 9.04
Awatar użytkownika
czp
Posty: 47
Rejestracja: czw mar 04, 2010 5:38 pm

Re: podwójna konkatenacja

Post autor: czp »

Do tej pory doszedłem jedynie w zapytaniu MySQL do takiej postaci:

Kod: Zaznacz cały

SELECT 
`id_rsd`,  CONCAT_WS('   ', CONVERT(`data`, CHAR(10)), `obieg`) AS `data i obieg`  
FROM `2010_obieg`; 
Ta kwerenda generuje mi już wynik z bazy tak jak pokazałem w poniższym pliku, ale zupełnie nie wiem jak zgrupować `id_rsd` przy jednoczesnym połączeniu pola `data i obieg`
Załączniki
opis2.odt
(14.59 KiB) Pobrany 200 razy
Windows 7 i openoffice 3.2
Jan_J
Posty: 4558
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: podwójna konkatenacja

Post autor: Jan_J »

Jest jasne, że trzeba użyć klauzuli GROUP BY, i że CONCAT_WS musi zrozumieć, co ma sumować. Powinna więc być tzw. funkcją agregującą.
Nie mam działającej kopii MySQL, więc nie przetestuję Twojego przykładu na żywo. Opis równoważnej procedury dla Postgresa dość łatwo było znaleźć, patrz http://stackoverflow.com/questions/4387 ... p-by-query. Działa out of the box.
JJ
LO (7.6|24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
mg2
Posty: 170
Rejestracja: czw sty 28, 2010 9:20 pm

Re: podwójna konkatenacja

Post autor: mg2 »

W MYSQL można zrobić CONCAT na dacie i liczbie

mysql> select * from t1;
+----+------+------------+
| id | a | d |
+----+------+------------+
| 1 | a | 2001-01-01 |
| 2 | a | 2001-01-02 |
+----+------+------------+

mysql> select concat(a, d) from t1;
+--------------+
| concat(a, d) |
+--------------+
| a2001-01-01 |
| a2001-01-02 |
+--------------+

mysql> select concat_ws(',', a, d) from t1;
+----------------------+
| concat_ws(',', a, d) |
+----------------------+
| a,2001-01-01 |
| a,2001-01-02 |
+----------------------+

ale rzeczywiście Base coś grymasi i trzeba zrobić

cast( concat(...) as char )

Wracając do tematu

mysql> select * from t1;
+----+------+------------+
| id | a | d |
+----+------+------------+
| 1 | a | 2001-01-01 |
| 2 | a | 2001-01-02 |
| 3 | b | 2001-01-03 |
| 4 | b | 2001-01-04 |
+----+------+------------+

mysql> select cast(group_concat(concat_ws(',', id, d)) as char), a from t1 group by a;
+---------------------------------------------------+------+
| cast(group_concat(concat_ws(',', id, d)) as char) | a |
+---------------------------------------------------+------+
| 1,2001-01-01,2,2001-01-02 | a |
| 3,2001-01-03,4,2001-01-04 | b |
+---------------------------------------------------+------+

i tak samo jest w Base tylko trzeba zakliknąć tryb bezpośredni w kwerendzie SQl.
OOo3.1.1 na Ubuntu 9.04
Awatar użytkownika
czp
Posty: 47
Rejestracja: czw mar 04, 2010 5:38 pm

Re: podwójna konkatenacja

Post autor: czp »

Dzięki za wskazówki.

No i działa - doszedłem do takiej postaci kwerendy:

Kod: Zaznacz cały

SELECT `id_rsd`,   GROUP_CONCAT(CONCAT_WS(' ', CONVERT(`data`, CHAR(10)), `obieg`) SEPARATOR ' \n ') as `data_obieg` FROM `2010_obieg` GROUP BY `id_rsd`;
Zostało mi tylko jedno malutkie ale, otóż separator, którego użyłem jak i inne nie chcą mi załamać linii (zupełnie nie wiem dlaczego) a przy większej ilości złączeń linia tekstu pola `data_obieg` jest strasznie długa lub zawinięta wg pola raportu ale jest przez to nieprzejrzysta,
Musi się to jakoś dać załamać , przed każdą kolejną datą ???
Windows 7 i openoffice 3.2
Jan_J
Posty: 4558
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: podwójna konkatenacja

Post autor: Jan_J »

A czy nie da się użyć fizycznego enter, tzn. 'zacząć string w jednym wierszu
a skończyć po enterze'? SQL to dopuszcza.

I jeszcze drobna uwaga natury estetycznej: czasem wygodniej zamiast notacji funkcyjnej
CONCAT(a, b)
używać operatora
a || b
Niby nic, ale łatwiej się czyta.
JJ
LO (7.6|24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
Awatar użytkownika
czp
Posty: 47
Rejestracja: czw mar 04, 2010 5:38 pm

Re: podwójna konkatenacja

Post autor: czp »

Uporałem się z tym przypadkiem.

Używam openoffice 3,2 i tam do tworzenia raportów miałem dogranego Base Sun Bulidera i on tak jak kwerenda nie potrafił wierszy załamać.
Usunąłem tego Bulidera i teraz przy tworzeniu raportów w base zwykłym kreatorem wiersze ładnie się łamią i każdy zaczyna od daty, czyli opcja separatora |\n| w raportach działa jak należy.
Windows 7 i openoffice 3.2
mg2
Posty: 170
Rejestracja: czw sty 28, 2010 9:20 pm

Re: podwójna konkatenacja

Post autor: mg2 »

I jeszcze drobna uwaga natury estetycznej: czasem wygodniej zamiast notacji funkcyjnej
CONCAT(a, b)
używać operatora
a || b
Niby nic, ale łatwiej się czyta.
Hmmmm ....

mysql> select * from t1;
+----+------+------------+
| id | a | d |
+----+------+------------+
| 1 | a | 2001-01-01 |
| 2 | a | 2001-01-02 |
| 3 | b | 2001-01-03 |
| 4 | b | 2001-01-04 |
+----+------+------------+
4 rows in set (0.00 sec)

mysql> select concat(id, a) from t1;
+---------------+
| concat(id, a) |
+---------------+
| 1a |
| 2a |
| 3b |
| 4b |
+---------------+
4 rows in set (0.00 sec)

mysql> select id || a from t1;
+---------+
| id || a |
+---------+
| 1 |
| 1 |
| 1 |
| 1 |
+---------+
4 rows in set (0.00 sec)
OOo3.1.1 na Ubuntu 9.04
Awatar użytkownika
czp
Posty: 47
Rejestracja: czw mar 04, 2010 5:38 pm

Re: podwójna konkatenacja

Post autor: czp »

operatorem konkatenacji w MySQL jest tylko funkcja CONCAT a nie operator ||.
Windows 7 i openoffice 3.2
Jan_J
Posty: 4558
Rejestracja: pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: podwójna konkatenacja

Post autor: Jan_J »

Hmmmm ....
macie rację. Moja uwaga dotyczyła standardu. Popularność popularnością, ale za coś nie lubię MySQL: za niezgodność ze standardem.
JJ
LO (7.6|24.2) ∙ Python (3.12|3.10) ∙ Unicode 15 ∙ LᴬTEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Rocky|CentOS)
ODPOWIEDZ