podwójna konkatenacja

Użytkowanie programu bazodanowego

podwójna konkatenacja

Postprzez czp » Śr kwi 14, 2010 1:27 pm

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) Pobrane 87 razy
konkatenacja.odb
(4.55 KiB) Pobrane 75 razy
Ostatnio edytowano Śr kwi 14, 2010 1:34 pm przez czp, łącznie edytowano 1 raz
Windows 7 i openoffice 3.2
Avatar użytkownika
czp
 
Posty: 47
Dołączył(a): Cz mar 04, 2010 5:38 pm

Re: podwójna konkatenacja

Postprzez Jan_J » Śr kwi 14, 2010 8:12 pm

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   Rozszerz widokZwiń widok
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 Still (6.2) ∙ AOO 4.1.7 ∙ Python (3.7|2.7) ∙ Unicode 12 ∙ LATEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Fedora|CentOS|SUSE)
Jan_J
 
Posty: 3968
Dołączył(a): Pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: podwójna konkatenacja

Postprzez czp » Śr kwi 14, 2010 8:44 pm

Dzięki

sprawdzam - base tylko dla przykładu a bazę mam w mysql.
Windows 7 i openoffice 3.2
Avatar użytkownika
czp
 
Posty: 47
Dołączył(a): Cz mar 04, 2010 5:38 pm

Re: podwójna konkatenacja

Postprzez mg2 » Śr kwi 14, 2010 9:45 pm

Można przepuścić tabelę przez makro zamieniające wiersze z kolumnami. (Calc ma taką funkcję).
OOo3.1.1 na Ubuntu 9.04
mg2
 
Posty: 170
Dołączył(a): Cz sty 28, 2010 9:20 pm

Re: podwójna konkatenacja

Postprzez czp » Cz kwi 15, 2010 10:25 am

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
Avatar użytkownika
czp
 
Posty: 47
Dołączył(a): Cz mar 04, 2010 5:38 pm

Re: podwójna konkatenacja

Postprzez mg2 » Cz kwi 15, 2010 3:46 pm

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
mg2
 
Posty: 170
Dołączył(a): Cz sty 28, 2010 9:20 pm

Re: podwójna konkatenacja

Postprzez czp » Pt kwi 16, 2010 4:54 pm

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

Kod: Zaznacz cały   Rozszerz widokZwiń widok
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) Pobrane 96 razy
Windows 7 i openoffice 3.2
Avatar użytkownika
czp
 
Posty: 47
Dołączył(a): Cz mar 04, 2010 5:38 pm

Re: podwójna konkatenacja

Postprzez Jan_J » Pt kwi 16, 2010 10:55 pm

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 Still (6.2) ∙ AOO 4.1.7 ∙ Python (3.7|2.7) ∙ Unicode 12 ∙ LATEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Fedora|CentOS|SUSE)
Jan_J
 
Posty: 3968
Dołączył(a): Pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: podwójna konkatenacja

Postprzez mg2 » So kwi 17, 2010 3:42 am

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
mg2
 
Posty: 170
Dołączył(a): Cz sty 28, 2010 9:20 pm

Re: podwójna konkatenacja

Postprzez czp » So kwi 17, 2010 9:33 pm

Dzięki za wskazówki.

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

Kod: Zaznacz cały   Rozszerz widokZwiń widok
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
Avatar użytkownika
czp
 
Posty: 47
Dołączył(a): Cz mar 04, 2010 5:38 pm

Re: podwójna konkatenacja

Postprzez Jan_J » So kwi 17, 2010 9:58 pm

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 Still (6.2) ∙ AOO 4.1.7 ∙ Python (3.7|2.7) ∙ Unicode 12 ∙ LATEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Fedora|CentOS|SUSE)
Jan_J
 
Posty: 3968
Dołączył(a): Pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław

Re: podwójna konkatenacja

Postprzez czp » So kwi 17, 2010 11:09 pm

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
Avatar użytkownika
czp
 
Posty: 47
Dołączył(a): Cz mar 04, 2010 5:38 pm

Re: podwójna konkatenacja

Postprzez mg2 » So kwi 17, 2010 11:31 pm

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
mg2
 
Posty: 170
Dołączył(a): Cz sty 28, 2010 9:20 pm

Re: podwójna konkatenacja

Postprzez czp » N kwi 18, 2010 6:43 am

operatorem konkatenacji w MySQL jest tylko funkcja CONCAT a nie operator ||.
Windows 7 i openoffice 3.2
Avatar użytkownika
czp
 
Posty: 47
Dołączył(a): Cz mar 04, 2010 5:38 pm

Re: podwójna konkatenacja

Postprzez Jan_J » N kwi 18, 2010 9:03 pm

Hmmmm ....
macie rację. Moja uwaga dotyczyła standardu. Popularność popularnością, ale za coś nie lubię MySQL: za niezgodność ze standardem.
JJ
LO Still (6.2) ∙ AOO 4.1.7 ∙ Python (3.7|2.7) ∙ Unicode 12 ∙ LATEX 2ε ∙ XML ∙ Unix tools ∙ Linux (Fedora|CentOS|SUSE)
Jan_J
 
Posty: 3968
Dołączył(a): Pt maja 22, 2009 1:20 pm
Lokalizacja: Wrocław


Powrót do Base

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 1 gość