# SQL - Ausgabe in Spalten



## Trebjun (3. März 2008)

Hallo,

ich habe folgendes Problem:

angenommen ich mache folgende SQL Abfrage:

SELECT * 
FROM tbl_autos

dann bekomme ich folgende Ausgabe

Audi
BMW
Mercedes
Porsche
...

Wie kann ich aber folgende Ausgabe umsetzen:

Audi  BWM  Mercedes  Porsche ... 

Ich möchte die Ausgaben also nicht in den Zeilen, sondern in den Spalten. Gibt es da eine einfache Möglichkeit? 

Gruss,
Trebjun


----------



## Gumbo (3. März 2008)

Meines Wissens ist nicht möglich. Wofür brauchst du das denn?


----------



## Trebjun (3. März 2008)

Echt, das ist wirklich nicht möglich? Mein Problem lässt sich schwer beschreiben ... von daher wäre es toll, wenn das gehen würde.


----------



## Gumbo (3. März 2008)

Trebjun hat gesagt.:


> Mein Problem lässt sich schwer beschreiben ...


Dann versuch’s doch einfach mal.


----------



## Trebjun (3. März 2008)

Okay ...

also, ich habe in meiner Datenbank-Tabelle 6 Spalten: sagen wir mal (A,B,C,D,E,F),

A      B        C         D        E        F
---------------------------------------------------------
...     ...       ...        ...       E.1      F.1
...     ...       ...        ...       E.2      F.2
...     ...       ...        ...       E.3      F.3
...


Nun soll ich einen Report daraus bauen, indem die ersten vier Spalten A-D normal ausgegben  werden und die Spalte E nicht senkrecht, sondern waagerecht auch als Spalte. Spalte F wird dann in den Spalten von E angezeigt. Also so ungefähr ...

A      B        C         D        E.1    E.2    E.3     E.4   ...
----------------------------------------------------------------------------------
...     ...       ...        ...        F.1                       F.2
...     ...       ...        ...                 F.1                       
...     ...       ...        ...        F.3              F.2        
...     ...       ...        ...        F.1    F.4
...

Ich hoffe das war jetzt einigermassen verständlich?!


----------



## Kyoko (3. März 2008)

Wie die Daten aus der Datenbank kommen ist doch egal, das Layout musst sowieso im Report-Generator festlegen?


----------



## planb2000 (3. März 2008)

Hallo,

erstmal DAS DATENBANKSYSTEM das Du benutzt ist WICHTIG !!

So, ansonsten ist Dein Zauberwort "transponieren": Wir brauchten das auch schon und machen das in Oracle so:

*Simulierte Spalte (geht glaub ich auch in MySQL):*

```
SELECT TYPE 
FROM 
(
SELECT 'zeile1spalte1' AS TYPE FROM dual
UNION
SELECT 'zeile2spalte1' AS TYPE FROM dual
UNION 
SELECT 'zeile3spalte1' AS TYPE FROM dual
)
```
*Ausgabe:*
TYPE
---------
zeile1spalte1
zeile2spalte1
zeile3spalte1

*jetzt die Funktion bauen (Beispiel ist für Oracle geeignet !!):*


```
PROMPT CREATE OR REPLACE FUNCTION rowtocol
CREATE OR REPLACE FUNCTION rowtocol( p_slct IN VARCHAR2,

     p_dlmtr IN VARCHAR2 DEFAULT ',' ) RETURN VARCHAR2

     AUTHID CURRENT_USER AS




--1) Column should be character type.
--2) If it is non-character type, column has to be converted into character type.
--3) If the returned rows should in a specified order, put that ORDER BY CLASS in the SELECT statement argument.
--4) If the SQL statement happened to return duplicate values, and if you don't want that to happen, put DISTINCT in the SELECT statement argument.



     TYPE c_refcur IS REF CURSOR;

     lc_str VARCHAR2(4000);

     lc_colval VARCHAR2(4000);

     c_dummy c_refcur;

     l number;


     BEGIN


     OPEN c_dummy FOR p_slct;



     LOOP

     FETCH c_dummy INTO lc_colval;

     EXIT WHEN c_dummy%NOTFOUND;

     lc_str := lc_str || p_dlmtr || lc_colval;

     END LOOP;

     CLOSE c_dummy;



     RETURN SUBSTR(lc_str,2);



     EXCEPTION

     WHEN OTHERS THEN



     lc_str := SQLERRM;

     IF c_dummy%ISOPEN THEN

     CLOSE c_dummy;

     END IF;

     RETURN lc_str;





     END;
/
```

*Jetzt die Funktion verwenden:*


```
SELECT '1' AS Spalte , rowtocol(

' SELECT TYPE FROM 
(
SELECT ''zeile2spalte1'' AS TYPE FROM dual
UNION
SELECT ''zeile2spalte2'' AS TYPE FROM dual
UNION 
SELECT ''zeile2spalte3'' AS TYPE FROM dual
)'
, ' ;' )  zeile
FROM dual
```
*Ausgabe:*
SPALTE	ZEILE
---------------------------------------------------------------------------
1             zeile1spalte1 ;zeile2spalte1 ;zeile3spalte1


Das ist der Werkzeugkasten mit dem Du (fast)alles lösen kannst.

Viel Spaß und sag bescheid obs geklappt hat.

Grüße


----------



## dbwizard (3. März 2008)

Trebjun hat gesagt.:


> Hallo,
> 
> ich habe folgendes Problem:
> 
> ...



- Welche DB ist es denn ?


Gruss


----------



## dbwizard (3. März 2008)

planb2000 hat gesagt.:


> Hallo,
> 
> erstmal DAS DATENBANKSYSTEM das Du benutzt ist WICHTIG !!
> 
> ...



-Coole Lösung 

...oder auch so :

CREATE OR REPLACE 
TYPE myscalartype AS OBJECT (
   job   VARCHAR2 (30))
/

CREATE OR REPLACE 
TYPE myarraytype AS TABLE OF myScalarType
/

SELECT CAST (MULTISET (SELECT   job
                           FROM emp
                       GROUP BY job) AS myArrayType) x
  FROM emp
/

(Basiert auf dem ScottTiger beispielschema...Falls der OP Oracle benutzt)


----------



## planb2000 (3. März 2008)

hey dbwizard,

die Lösung von Dir geht bei mir leider nicht, sieht ja genial einfach aus, ist die für Oracle 10g ?

Bekomme immer die Meldung: "The Query fails because all columns types are currently not supported" -> benutze Oracle 9.2i

Grüße


----------



## Trebjun (3. März 2008)

Danke schon mal für die Antworten und Tipps!

Leider arbeiten wir noch mit SQL Server 2000, da gibt es leider keine Funktion rowtocol: ;-(
Wäre ja auch zu schön gewesen! Würde mich aber nicht wundern, wenn das bei SQL Server 2005 geht. Für 2000 gibt's wahrscheinlich keine Lösung, oder?


----------



## dbwizard (3. März 2008)

planb2000 hat gesagt.:


> hey dbwizard,
> 
> die Lösung von Dir geht bei mir leider nicht, sieht ja genial einfach aus, ist die für Oracle 10g ?
> 
> ...



- nö, sollte auch in 9.2 funktionieren :

Guckst du :

oracle@CHTHL-TUX-ORACLE2:/usr/data/oracle/scripting/dba> sqlplus scott/tiger

SQL*Plus: Release 9.2.0.8.0 - Production on Mon Mar 3 14:51:23 2008

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

Connected to:
Oracle9i Enterprise Edition Release 9.2.0.8.0 - 64bit Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.8.0 - Production

SQL> CREATE OR REPLACE TYPE myscalartype AS OBJECT (job VARCHAR2 (30))
  2  /

Type created.

SQL> CREATE OR REPLACE TYPE myarraytype AS TABLE OF myScalarType
  2  /

Type created.

SQL> SELECT CAST (MULTISET (SELECT job FROM emp GROUP BY job) AS myArrayType) x
FROM emp
  2  /

X(JOB)
--------------------------------------------------------------------------------
MYARRAYTYPE(MYSCALARTYPE('ANALYST'), MYSCALARTYPE('CLERK'), MYSCALARTYPE('MANAGE
R'), MYSCALARTYPE('PRESIDENT'), MYSCALARTYPE('SALESMAN'))

MYARRAYTYPE(MYSCALARTYPE('ANALYST'), MYSCALARTYPE('CLERK'), MYSCALARTYPE('MANAGE
R'), MYSCALARTYPE('PRESIDENT'), MYSCALARTYPE('SALESMAN'))

MYARRAYTYPE(MYSCALARTYPE('ANALYST'), MYSCALARTYPE('CLERK'), MYSCALARTYPE('MANAGE
R'), MYSCALARTYPE('PRESIDENT'), MYSCALARTYPE('SALESMAN'))

MYARRAYTYPE(MYSCALARTYPE('ANALYST'), MYSCALARTYPE('CLERK'), MYSCALARTYPE('MANAGE
R'), MYSCALARTYPE('PRESIDENT'), MYSCALARTYPE('SALESMAN'))

X(JOB)
--------------------------------------------------------------------------------

MYARRAYTYPE(MYSCALARTYPE('ANALYST'), MYSCALARTYPE('CLERK'), MYSCALARTYPE('MANAGE
R'), MYSCALARTYPE('PRESIDENT'), MYSCALARTYPE('SALESMAN'))

MYARRAYTYPE(MYSCALARTYPE('ANALYST'), MYSCALARTYPE('CLERK'), MYSCALARTYPE('MANAGE
R'), MYSCALARTYPE('PRESIDENT'), MYSCALARTYPE('SALESMAN'))

MYARRAYTYPE(MYSCALARTYPE('ANALYST'), MYSCALARTYPE('CLERK'), MYSCALARTYPE('MANAGE
R'), MYSCALARTYPE('PRESIDENT'), MYSCALARTYPE('SALESMAN'))

MYARRAYTYPE(MYSCALARTYPE('ANALYST'), MYSCALARTYPE('CLERK'), MYSCALARTYPE('MANAGE

X(JOB)
--------------------------------------------------------------------------------
R'), MYSCALARTYPE('PRESIDENT'), MYSCALARTYPE('SALESMAN'))

MYARRAYTYPE(MYSCALARTYPE('ANALYST'), MYSCALARTYPE('CLERK'), MYSCALARTYPE('MANAGE
R'), MYSCALARTYPE('PRESIDENT'), MYSCALARTYPE('SALESMAN'))

MYARRAYTYPE(MYSCALARTYPE('ANALYST'), MYSCALARTYPE('CLERK'), MYSCALARTYPE('MANAGE
R'), MYSCALARTYPE('PRESIDENT'), MYSCALARTYPE('SALESMAN'))

MYARRAYTYPE(MYSCALARTYPE('ANALYST'), MYSCALARTYPE('CLERK'), MYSCALARTYPE('MANAGE
R'), MYSCALARTYPE('PRESIDENT'), MYSCALARTYPE('SALESMAN'))


X(JOB)
--------------------------------------------------------------------------------
MYARRAYTYPE(MYSCALARTYPE('ANALYST'), MYSCALARTYPE('CLERK'), MYSCALARTYPE('MANAGE
R'), MYSCALARTYPE('PRESIDENT'), MYSCALARTYPE('SALESMAN'))

MYARRAYTYPE(MYSCALARTYPE('ANALYST'), MYSCALARTYPE('CLERK'), MYSCALARTYPE('MANAGE
R'), MYSCALARTYPE('PRESIDENT'), MYSCALARTYPE('SALESMAN'))

MYARRAYTYPE(MYSCALARTYPE('ANALYST'), MYSCALARTYPE('CLERK'), MYSCALARTYPE('MANAGE
R'), MYSCALARTYPE('PRESIDENT'), MYSCALARTYPE('SALESMAN'))


14 rows selected.

SQL>


----------



## planb2000 (3. März 2008)

hallo trebjun,

die gibt es auch nicht mitgeliefert, die Funktion mußt Du auf Die Sprache im SQL Server anpassen. Die Synthax sieht ähnlich aus 
Beispiel:

```
CREATE FUNCTION dbo.LookByFName(@FirstLetter char(1))
RETURNS TABLE
AS
RETURN SELECT *
FROM employee
WHERE LEFT(fname, 1) =  @FirstLetter
```

Wenn ich schaue die haben sogar Pivot Tabelle als option : http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1416744&SiteID=1, sieht aus wie ein Beispiel.

Grüße


----------



## dbwizard (3. März 2008)

planb2000 hat gesagt.:


> hey dbwizard,
> 
> die Lösung von Dir geht bei mir leider nicht, sieht ja genial einfach aus, ist die für Oracle 10g ?
> 
> ...



- BTW, in Oracle 11 geht es noch eleganter 
--> http://www.oracle.com/technology/pub/articles/oracle-database-11g-top-features/11g-pivot.html


Gruss


----------



## Trebjun (3. März 2008)

.... ich dachte nicht, dass das so kompliziert ist ... aber wahrscheinlich stelle ich mich auch nur unwahrscheinlich blöd an ...  ... ich werde es aber weiterhin versuchen. Mit den PivotTable müsste es wahrscheinlich klappen, bin aber noch am tüfteln 

Danke


----------

