[DB2] Mehrere werte in einer Zelle

JesusFreak777

Erfahrenes Mitglied
Hi ihr,
ist es denn möglich in einer Zelle mehrere Werte einzufügen:
also SELECT feld1 & feld2 AS combi ...
mein Ziel ist folgendes:
ich habe Zwei Tabellen, etwa so:
Code:
TBL1
ID     | ID2    | WERT    | KLASSE
1      |        | 25      | 1
2      | 1      | 56      | 3
3      | 2      | 1       | 3
4      |        | 23      | 1
TBL2
ID     | PID   | CODE | NR
1      | 1     | 10   | 10
2      | 1     | 15   | 20
3      | 2     | 10   | 10
4      |       | 55   | 80
Ziel ist es folgendes zu erhalten:
Code:
QUERY
WERT    | KLASSE
25      | 1
56      | #10#15
1       | #10
23      | 1
        | #55
- alle werte aus TBL1
- wenn klasse 1 dann KLASSE => 1
- wenn klasse 3 dann alle werte aus TBL2 (ID2 == PID) mit Raute ins KLASSE Feld (das wird dann in PHP weiterverarbeitet)
- jetzt gibt es in TBL2 noch felder ohne PID (bei denen ist NR immer 80) -> diese müssen auch alle (einzeln) in meine QUERY
das ganze bekommt dann noch eine WHERE DATE >= 'irgendein datum'.
ist sowas überhaupt mit einen QUERY möglich?
Vielen Dank
 
Ich geh mal von MySQL aus.
Das geht locker. Mit UNION, CONCAT und GROUP_CONCAT
http://sqlfiddle.com/#!2/3f7c79/3
SQL:
-- Alle der Klasse 1
SELECT
  tbl1.wert,
  tbl1.klasse
FROM
  tbl1
WHERE
  tbl1.klasse = 1
-- Alle der Klasse 3
UNION ALL
SELECT
  tbl1.wert,
  CONCAT('#', GROUP_CONCAT(tbl2.code SEPARATOR '#')) AS klasse
FROM
  tbl1,
  tbl2
WHERE
  tbl1.klasse=3
  AND tbl1.id2 = tbl2.pid
GROUP BY
  tbl1.wert
-- Alle tbl2 id keine pid haben
UNION ALL
SELECT
  NULL AS wert,
  CONCAT('#', tbl2.code) AS klasse
FROM
  tbl2
WHERE
  tbl2.pid IS NULL
 
hm,... leider bin ich (mir meinem wissen) in einer Sackgasse :/
online finde ich Zwei Möglichkeiten...
1. Schreibe eine Funktion
2. mach das "irgendwie" über eine XMLfunktion
beides übersteigt mein wissen...
=> meine erste Idee war, ich ruf einfach die Daten ab und verarbeite sie in PHP (weil darin bin ich besser :) ...) aber leider sind das so viele Daten, das die Ladezeit mit Probleme bereitet.
das hab ich im internetz gefunden:
Code:
with recursive rpl (artnr, suchb) 
as (select a.artnr, a.suchb from myfile a 
union all
select rpl.artnr, rpl.suchb
concat ', ' concat b.suchb 
from rpl, myfile b 
where rpl.art=b.art and rpl.art<>b.art
) 
select * from rpl
<- aber wie wende ich das auf meinen szenario an?
auch das habe ich gefunden (für CONCAT):
Code:
'#' || CHAR( tbl2.CODE) AS KLASSE
das geht leider nich :/
und das habe ich gefunden:
Code:
xmlserialize(XMLAGG(XMLELEMENT(NAME "x", id) ) as varchar(1000))
da hab ich dann wieder probleme mit der umsetzung :/
hat jemand Erfahrung mit DB2 danke :)
 
gerade habe ich noch das gefunden... evtl. hilft das weiter...
kann jemand das auf mein Problem abändern?
Code:
WITH
children_numbered(rowNum, parent_name, child_name) AS
(
SELECT rownumber() over(partition by parent_name),
parent_name, child_name
FROM children
),
children_grouped (parent_name, list, idx) AS
(
SELECT parent_name, child_name, 1
FROM children_numbered
WHERE rowNum = 1
UNION ALL
SELECT
children_grouped.parent_name,
children_grouped.list || ', ' || children_numbered.child_name,
children_grouped.idx + 1
FROM children_grouped, children_numbered
WHERE
children_grouped.parent_name = children_numbered.parent_name
AND children_grouped.idx + 1 = children_numbered.rowNum
)
SELECT parent_name, list
FROM children_grouped
WHERE ( parent_name, idx ) IN (
SELECT parent_name, MAX(rowNum)
FROM children_numbered
GROUP BY parent_name )
ORDER BY 1

ich will alle gleichen PID aus einer tabelle gruppieren und eine # voranstellen (wegen mir auch andere "trennzeichen")!

leider muss ich noch hinzufügen das ich DB" ver 9.5 habe :/ ... Aktualisierung nicht möglich :(
 
Zuletzt bearbeitet:
Also grundsätzlich hat dir Yaslaw ja bereits gezeigt wie es geht. 3 voneinander Separate Queries welche man mit UNION ALL verbindet. Klasse 1 und die codes mit nr = 80 sollten ja einfach sein.

Ich kenne DB2 nicht aber google. Zu concat: so wie ich das verstehe kennt DB2 concat:
http://www-01.ibm.com/support/knowl...doc/r0000781.html?cp=SSEPGG_9.7.0/2-10-3-2-25
Es geht auch double pipe, aber IBM empfiehlt concat:
http://stackoverflow.com/questions/15231631/db2-concat-vs-double-pipe

Zu dem group concat aus mysql gäbe es bei DB2 9.7 offenbar LISTAGG:
http://www-01.ibm.com/support/knowl.../doc/r0058709.html?cp=SSEPGG_9.7.0/2-10-3-1-7
Aber du schreibst ja, dass du nur 9.5 hast. Daher wohl mit XML:
http://stackoverflow.com/questions/15161027/db2-sql-grouping-records-with-same-id-in-result

Bei dir musst du wohl zuerst in einer eigenen Subquery mit xmlserialize, xmlagg und xmltext pro PID auf eine row aggregieren. Danach kannst du dann diese Resultat einfach dazu joinen. Da ich aber DB2 selber nicht kenne und nicht testen kann, musst du das halt mal selber versuchen.
 
Hi ihr,
soooo, bin jetzt n ganzes Stück weiter:
Code:
SELECT
         ROWNUMBER() OVER() AS NUM,
         tbl2.WNNR,
         tbl2.CRDATE,
         tbl2.CRTIME,
         replace(replace(xml2clob(xmlagg(xmlelement(NAME a, tbl2.PART_ERR_NUM))),'<A>', '#'), '</A>', '') AS SORT_KLASSE
        FROM
         administrator.REC_HIST as tbl1,
         administrator.ERR_LOG_HIST as tbl2
        WHERE
         tbl1.WNNR = '".$mtit."'
         AND tbl1.SORT_KLASSE = 3
          AND tbl1.CRDATE = tbl2.CRDATE
         AND tbl1.CRTIME = tbl2.CRTIME
         AND tbl1.CRDATE >= '".$from."'
         AND tbl1.CRDATE <= '".$to."'
         AND NOT tbl2.PART_P_NR = '80'
        GROUP BY
        tbl2.CRTIME, tbl2.CRDATE, tbl2.WNNR

hier mal mit "ECHTEN" bezeichnungen!!!

kurze erklärung:
es werden in tbl1 daten geschrieben mit WNNR (Artikelnummer), CRDATE (Prüf-Datum), CRTIME (Prüf-Zeit mit Sekunden), SORT_KLASSE (1 für OKAY 3 für nicht OKAY)

wenn ein teil nicht OKAY ist, wird nicht nur in tbl1.SORT_KLASSE ein Wert eingetragen sondern auch in tbl2 "alle" Fehler (das können 1 - max 10 (zu 99% aber eher 3 -> durchschnittlich haben wir 2 Fehler pro "nicht OKAY").

=> da die Maschine CRDATE und CRTIME übergibt, sind diese Identisch und als "ID" zu betrachten... -> mit der abfrage "WHERE tbl1.CRTIME = tbl2.CRTIME" versuch ich also die "SELBEN TEILE" mit den "UNTERSCHIEDLICHEN FEHLERN" aufzulisten:
TEIL 47 -> Fehler1, Fehler3
TEIL 50 -> Fehler7, Fehler2, Fehler8
...
In meiner "REC_HIST" -> tbl1 habe ich bei meinem Aktuellen abruf 74 Fehlerfälle (SORT_KLASSE = 3)
In meiner "ERR_LOG_HIST" -> tbl2 habe ich nach abruf 221 Fehler (wovon ~60 Fehler manuell dazugekommen sind <- d.h. momentan uninteressant sind) => effektiv ~160 Fehler!
Nach meinen Abruf (wie oben im CODE) bekomm ich 10 Zeilen zurückgegeben, bei SORT_KLASSE stehen (zusammengezählt) 24 Fehler.
Warum ist das so? Erwartet habe ich alle 74 Fehlerfälle (jedes in einer Zeile) und in SORT_KLASSE alle ~160 Fehlercodes!!!
Was mach ich Falsch?
 
habe gerade gesehen, dieser abruf bringt mir 74 einträge:
Code:
SELECT
  CRDATE, CRTIME, SORT_KLASSE, PROD_NR 
FROM
  administrator.REC_HIST
WHERE
  CRDATE >= '".$from."'
  AND CRDATE <= '".$to."'
  AND WNNR = '".$mtit."'
  AND SORT_KLASSE = 3
dieser abruf:
Code:
SELECT
  ROWNUMBER() OVER() AS NUM,
  tbl2.WNNR,
  tbl2.CRDATE,
  tbl2.CRTIME
FROM
  administrator.REC_HIST as tbl1,
  administrator.ERR_LOG_HIST as tbl2
WHERE
  tbl1.WNNR = '".$mtit."'
  AND tbl1.SORT_KLASSE = 3
  AND tbl1.CRDATE = tbl2.CRDATE
  AND tbl1.CRTIME = tbl2.CRTIME
  AND NOT tbl2.PART_P_NR = '80'
  AND tbl1.CRDATE >= '".$from."'
  AND tbl1.CRDATE <= '".$to."'
GROUP BY
tbl2.CRTIME, tbl2.CRDATE, tbl2.WNNR
nur 10 Einträge...
hier ist ein einfacher Fehler der auch mit MySQL oder SQL Kenntnissen (die ich leider nich so habe) lösbar sein könnte...
Ich wäre soooo dankebar :)
 
=> da die Maschine CRDATE und CRTIME übergibt, sind diese Identisch und als "ID" zu betrachten... -> mit der abfrage "WHERE tbl1.CRTIME = tbl2.CRTIME" versuch ich also die "SELBEN TEILE" mit den "UNTERSCHIEDLICHEN FEHLERN" aufzulisten:
Wow echt?! Deine 'IDs' sind Zeitstempel? Du hast keine echten ID's in einer PK-FK Relation die du verwenden könntest? Naja, ich nehme mal an du kennst die Tabellen selber am besten und weist schon was du machst. Ist einfach ein bisschen speziell anzuschauen.

In meiner "REC_HIST" -> tbl1 habe ich bei meinem Aktuellen abruf 74 Fehlerfälle (SORT_KLASSE = 3)
In meiner "ERR_LOG_HIST" -> tbl2 habe ich nach abruf 221 Fehler (wovon ~60 Fehler manuell dazugekommen sind <- d.h. momentan uninteressant sind) => effektiv ~160 Fehler!
Nach meinen Abruf (wie oben im CODE) bekomm ich 10 Zeilen zurückgegeben, bei SORT_KLASSE stehen (zusammengezählt) 24 Fehler.
Warum ist das so? Erwartet habe ich alle 74 Fehlerfälle (jedes in einer Zeile) und in SORT_KLASSE alle ~160 Fehlercodes!!!
Was mach ich Falsch?
Von deiner Beschreibung her hätte ich das jetz auch erwartet. Aber wie gesagt machst du hier Inner Join auf Zeitstempel, sprich falls nur eine Milisekunde unterschied sein sollte, fällt der Record raus.

AND NOT tbl2.PART_P_NR = '80'
Kenne wie gesagt DB2 nicht, aber bei Oracle würde ich das Schreiben:
SQL:
  AND tbl2.PART_P_NR <> '80'
order auch
SQL:
  AND tbl2.PART_P_NR != '80'
Was ist der Datentyp von PART_P_NR? Falls ein String dan so. Falls eine Zahl dann besser als 80

Dann würde ich die JOIN Syntax verwenden. Anstatt:
FROM
administrator.REC_HIST as tbl1,
administrator.ERR_LOG_HIST as tbl2
WHERE
tbl1.WNNR = '".$mtit."'
AND tbl1.SORT_KLASSE = 3
AND tbl1.CRDATE = tbl2.CRDATE
AND tbl1.CRTIME = tbl2.CRTIME

So:
SQL:
FROM
  administrator.REC_HIST as tbl1
INNER JOIN
  administrator.ERR_LOG_HIST as tbl2
ON
  tbl1.CRDATE = tbl2.CRDATE
  AND tbl1.CRTIME = tbl2.CRTIME
WHERE ....
 
Zurück