Reputation: 7260
Table:
CREATE TABLE EMPDetails
(
ID int,
EmpName varchar(20),
ColumnName varchar(20),
ColumnValue varchar(20)
);
Records:
INSERT INTO EMPDetails Values(1,'S','Company','Microsoft');
INSERT INTO EMPDetails Values(1,'S','Profession','Database');
INSERT INTO EMPDetails Values(1,'S','Location','USA');
INSERT INTO EMPDetails Values(1,'S','Company','Unisys');
INSERT INTO EMPDetails Values(1,'S','Company','TATA');
INSERT INTO EMPDetails Values(2,'U','Company','Microsoft');
INSERT INTO EMPDetails Values(2,'U','Profession','Software');
INSERT INTO EMPDetails Values(2,'U','Location','UK');
INSERT INTO EMPDetails Values(2,'U','Company','DXC');
INSERT INTO EMPDetails Values(2,'U','Company','AOL');
INSERT INTO EMPDetails Values(3,'R','Company','Microsoft');
INSERT INTO EMPDetails Values(3,'R','Profession','Software');
INSERT INTO EMPDetails Values(3,'R','Location','UK');
INSERT INTO EMPDetails Values(3,'R','Company','AOL');
My try
Condition 1 : Company = 'Microsoft' AND Profession = 'Database'
Expected Result:
ID EmpName Company Profession Location
-----------------------------------------
1 S Microsoft Database USA
Query:
SELECT *
FROM
(
SELECT ID, EmpName,ColumnValue, ColumnName
FROM EMPDetails
) src
PIVOT
(
MAX(ColumnValue) /*OR MIN()*/
FOR ColumnName in ([Company], [Profession], [Location])
) piv
WHERE Company = 'Microsoft' AND Profession = 'Database'
Condition 2 : Company = 'Microsoft' AND Profession = 'Software'
Expected Result:
ID EmpName Company Profession Location
-----------------------------------------
3 R Microsoft Software UK
2 U Microsoft Software UK
Query :
SELECT *
FROM
(
SELECT ID, EmpName,ColumnValue, ColumnName
FROM EMPDetails
) src
PIVOT
(
MAX(ColumnValue) /*OR MIN()*/
FOR ColumnName in ([Company], [Profession], [Location])
) piv
WHERE Company = 'Microsoft' AND Profession = 'Software'
Question: If I use MIN()
aggregate function with condition 1, then will get result but not with MAX()
and it's reverse for condition 2. Why?
Upvotes: 2
Views: 55
Reputation: 72165
You can GROUP BY
employee and use conditional counting in the HAVING
clause, to get the employee that satisfies the criteria:
SELECT ID, EmpName
FROM EMPDetails
GROUP BY ID, EmpName
HAVING COUNT(CASE
WHEN ColumnName = 'Company' AND
ColumnValue = 'Microsoft' THEN 1
END) > 0
AND
COUNT(CASE
WHEN ColumnName = 'Profession' AND
ColumnValue = 'Database' THEN 1
END) > 0
The above query picks employees having Microsoft
as a Company
and Database
as a Profession
.
Output:
ID EmpName
------------
1 S
You can now use conditional aggregation to pivot the employee rows:
SELECT ID, EmpName,
'Microsoft' AS Company,
'Database' AS Profession,
MAX(CASE WHEN ColumnName = 'Location' THEN ColumnValue END) AS Location
FROM EMPDetails
GROUP BY ID, EmpName
HAVING COUNT(CASE
WHEN ColumnName = 'Company' AND
ColumnValue = 'Microsoft' THEN 1
END) > 0
AND
COUNT(CASE
WHEN ColumnName = 'Profession' AND
ColumnValue = 'Database' THEN 1
END) > 0
There is no need to perform aggregation for the Company or the Profession value, as the desired value is guaranteed to belong to the employee group.
Output:
ID EmpName Company Profession Location
-----------------------------------------
1 S Microsoft Database USA
To get the second result set, you can simply replace Database
by Software
:
SELECT ID, EmpName,
'Microsoft' AS Company,
'Software' AS Profession,
MAX(CASE WHEN ColumnName = 'Location' THEN ColumnValue END) AS Location
FROM EMPDetails
GROUP BY ID, EmpName
HAVING COUNT(CASE
WHEN ColumnName = 'Company' AND
ColumnValue = 'Microsoft' THEN 1
END) > 0
AND
COUNT(CASE
WHEN ColumnName = 'Profession' AND
ColumnValue = 'Software' THEN 1
END) > 0
Output:
ID EmpName Company Profession Location
---------------------------------------------
3 R Microsoft Software UK
2 U Microsoft Software UK
Upvotes: 1