I have a table with data showing different codes and descriptions used at different locations. I need to combine these locations into one. Before I can do that, I need to be able to clearly see two sets of data, the different descriptions used for a code in a given category at a given location, and the different codes used for a description in a given category at a given location, so I can get the data to agree. While a given code will only have one description per category per location, a given description can have multiple codes per category per location. I am only concerned with the cases where the codes and categories are used differently at the various locations. For these purposes a code or description that is the same at one or more locations, but is not used at the others is not different.
I need to be able to run one query that will show us, for a given category and code, all of the descriptions by location, including nulls where that code is not used, where the descriptions are not the same across all locations. Again, if the code has no differences other than null, it should not be on the list.
I need to be able to run another query that will show us, for a given category and description, ALL of the codes by location, including nulls where that description is not used, where the codes are not the same across all locations, keeping in mind that there may be more than one code per location. Again as above, if the codes are the same for a given category and description, but isn't used at all locations, it should not be returned.
So, if my table has:
LOCATION CATEGORY CODE DESCR
aaa Dept 001 Pharmacy
bbb Dept 001 Pharmacy
ccc Dept 002 Pharmacy
ddd Dept 002 Labratory
aaa Dept 003 Clerical
bbb Dept 003 Laundry
ccc Dept 003 IT
ddd Dept 003 Accounting
aaa Dept 004 Purchasing
bbb Dept 004 Purchasing
ccc Dept 004 Purchasing
ddd Dept 004 Purchasing
aaa Job 004 Recepionist
bbb Job 004 Recepionist
bbb Job 104 Recepionist
ccc Job 004 Recepionist
ddd Job 004 Recepionist
Same Code Different Descriptions
CATEGORY CODE aaa_DESCR bbb_DESCR ccc_DESCR ddd_DESCR
Dept 002 NULL NULL Pharmacy Labratory
Dept 003 Clerical Laundry IT Accounting
Same Description Different Codes
CATEGORY DESCR aaa_CODE1 bbb_CODE1 bbb_CODE2 ccc_CODE1 ddd_CODE1
Dept Pharmacy 001 001 NULL 002 NULL
Job Recepionist 004 004 104 004 004
If having multiple columns where there are multiple codes for the same description at a given location isn't possible, then perhaps it would be possible to put all the codes for that location in one column seperated by a specificed character, like this:
CATEGORY DESCR aaa_CODE bbb_CODE ccc_CODE ddd_CODE
Dept Pharmacy 001 001 002 NULL
Job Recepionist 004 004|104 004 004
The first step you need is to identify the rows you need to format, so for your first criterion where you want to find where the same code and category have more than one description, I would use EXISTS
:
SELECT t.Location, t.Category, t.Code, t.Descr
FROM #T AS t
WHERE EXISTS
( SELECT 1
FROM #T AS t2
WHERE t2.Category = t.Category
AND t2.Code = t.Code
AND t2.Descr != t.Descr
);
This gives the rows we need to format:
Location Category Code Descr
-------------------------------------------
ccc Dept 002 Pharmacy
ddd Dept 002 Labratory
aaa Dept 003 Clerical
bbb Dept 003 Laundry
ccc Dept 003 IT
ddd Dept 003 Accounting
Then, if you have a unique Desc
per category, code and location, as we do here you can simply use an arbitrary aggregate inside the PIVOT
function to get your desired format:
SELECT pvt.Category,
pvt.[aaa],
pvt.[bbb],
pvt.[ccc],
pvt.[ddd]
FROM ( SELECT t.Location, t.Category, t.Code, t.Descr
FROM #T AS t
WHERE EXISTS
( SELECT 1
FROM #T AS t2
WHERE t2.Category = t.Category
AND t2.Code = t.Code
AND t2.Descr != t.Descr
)
) AS t
PIVOT
( MAX(Descr)
FOR Location IN ([aaa], [bbb], [ccc], [ddd])
) AS pvt;
It gets more complicated when you might have more than one value, so you can't simply use MAX
inside PIVOT
. Here, you will need to use SQL Server's XML extensions to concatenate your similar rows into a single row .
The following uses the same EXISTS
logic to find the correct rows, but then rather than just selecting the Code
uses a subuqery to collect all the codes for that particular combination of (Category, Location, Descr)
and combines them into a single record:
SELECT t.Location,
t.Category,
t.Descr,
Code = STUFF(( SELECT '|' + t2.Code
FROM #T AS t2
WHERE t2.Category = t.Category
AND t2.Descr = t.Descr
AND t2.Location = t.Location
FOR XML PATH(''), TYPE
).value('.', 'VARCHAR(MAX)'), 1, 1, '')
FROM #T AS t
WHERE EXISTS
( SELECT 1
FROM #T AS t2
WHERE t2.Category = t.Category
AND t2.Descr = t.Descr
AND t2.Code != t.Code
)
GROUP BY t.Location, t.Category, t.Descr;
This gives:
Location Category Descr Code
--------------------------------------------
aaa Dept Pharmacy 001
aaa Job Recepionist 004
bbb Dept Pharmacy 001
bbb Job Recepionist 004|104
ccc Dept Pharmacy 002
ccc Job Recepionist 004
ddd Job Recepionist 004
Once you have this format, you can again use PIVOT
to get your desired output.
SELECT pvt.Category,
pvt.[aaa],
pvt.[bbb],
pvt.[ccc],
pvt.[ddd]
FROM ( SELECT t.Location,
t.Category,
t.Descr,
Code = STUFF(( SELECT '|' + t2.Code
FROM #T AS t2
WHERE t2.Category = t.Category
AND t2.Descr = t.Descr
AND t2.Location = t.Location
FOR XML PATH(''), TYPE
).value('.', 'VARCHAR(MAX)'), 1, 1, '')
FROM #T AS t
WHERE EXISTS
( SELECT 1
FROM #T AS t2
WHERE t2.Category = t.Category
AND t2.Descr = t.Descr
AND t2.Code != t.Code
)
GROUP BY t.Location, t.Category, t.Descr
) AS t
PIVOT
( MAX(Code)
FOR Location IN ([aaa], [bbb], [ccc], [ddd])
) AS pvt;
Examples of Both Queries on SQL Fiddle
For completeness below is the table I used for testing:
CREATE TABLE #T (Location VARCHAR(3), Category VARCHAR(4), Code CHAR(3), Descr VARCHAR(50));
INSERT INTO #T (Location, Category, Code, Descr)
VALUES
('aaa', 'Dept', '001', 'Pharmacy'),
('bbb', 'Dept', '001', 'Pharmacy'),
('ccc', 'Dept', '002', 'Pharmacy'),
('ddd', 'Dept', '002', 'Labratory'),
('aaa', 'Dept', '003', 'Clerical'),
('bbb', 'Dept', '003', 'Laundry'),
('ccc', 'Dept', '003', 'IT'),
('ddd', 'Dept', '003', 'Accounting'),
('aaa', 'Dept', '004', 'Purchasing'),
('bbb', 'Dept', '004', 'Purchasing'),
('ccc', 'Dept', '004', 'Purchasing'),
('ddd', 'Dept', '004', 'Purchasing'),
('aaa', 'Job', '004', 'Recepionist'),
('bbb', 'Job', '004', 'Recepionist'),
('bbb', 'Job', '104', 'Recepionist'),
('ccc', 'Job', '004', 'Recepionist'),
('ddd', 'Job', '004', 'Recepionist');
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.