I have the following table (simplified from reality).
| ID | String_AttributeName | String_AttributeValue | Int_AttributeName | Int_AttributeValue |
|----|----------------------|-----------------------|-------------------|--------------------|
| 1 | Name | Object1 | | |
| 1 | (null) | (null) | Age | 5 |
| 2 | Name | Object2 | | |
| 2 | Location | Canada | (null) | (null) |
| 2 | (null) | (null) | Quantity | 2 |
| 3 | Name | Object3 | | |
| 3 | (null) | (null) | Age | 3 |
| 3 | (null) | (null) | Quantity | 4 |
Basically, I have multiple items (which are differentiated by the ID
column) described in the table by the 4 attribute columns.
The way it works is that for each AttributeName
column, there is a value, represented by the AttributeValue
column. Each attribute is separated according to its type (there are string, int, bool, etc. I will only show 2 to simplify the problem).
When I say AttributeName
, it means either column #2 or #4. Every item (ID
column) is described in multiple lines, where each line may only contain one attribute (the other will be null). Therefore, There may not be 2 AttributeName
in the same row. Also, not all objects have every existing attribute (ID 3 has all attributes while 1 and 2 don't); however, doing a DISTINCT SELECT
in the AttributeName
of either type will select every AttributeName
possibility
My goal is the following (explications below):
+----+---------+--------+----------+
| ID | Name | Age | Quantity |
+----+---------+--------+----------+
| 1 | Object1 | 5 | (null) |
+----+---------+--------+----------+
| 2 | Object2 | (null) | 2 |
+----+---------+--------+----------+
| 3 | Object3 | 3 | 4 |
+----+---------+--------+----------+
As you can see, I want each attribute, no matter its type (int, string, etc.) to be a column and the result be in the corresponding row of every item. Also, there are more than 50 different attributes and they can change with time, so something that changes dynamically would be the best.
I've tried the PIVOT
function, but, first, I don't think that it will work, since there is no aggregation, and second, i do not want a null column. My query is also not functioning, since there is a "missing expression"
Here it is:
SELECT *
FROM
(
SELECT ID
,STRING_ATTRIBUTENAME
FROM PIVOTTABLE
)
PIVOT
(
COUNT(STRING_ATTRIBUTENAME)
FOR STRING_ATTRIBUTENAME IN (SELECT DISTINCT PIVOTTABLE.STRING_ATTRIBUTENAME FROM PIVOTTABLE)
)
ORDER BY PARTNUMBER;
It's been a while I last did SQL development (I used to do SQL Server), so it is a bit rusty. I just have no clue of else to try, I'm currently looking if there is a way to do some dynamic SQL with a select of the AttributeName
column.
Any clues will also help. Thanks !
------------ Here is for recreating the start table:
CREATE TABLE PIVOTTABLE
(
ID NUMBER NOT NULL
, STRING_ATTRIBUTENAME VARCHAR2(50)
, STRING_ATTRIBUTEVALUE VARCHAR2(50)
, INT_ATTRIBUTENAME VARCHAR2(50)
, INT_ATTRIBUTEVALUE NUMBER
);
INSERT INTO TestTable VALUES('1','Name','Object1','','')
INSERT INTO TestTable VALUES('1','','','Age','5')
INSERT INTO TestTable VALUES('2','Name','Object2','','')
INSERT INTO TestTable VALUES('2','','','Quantity','2')
INSERT INTO TestTable VALUES('3','Name','Object3','','')
INSERT INTO TestTable VALUES('3','','','Age','3')
INSERT INTO TestTable VALUES('3','','','Quantity','4')