我已经尽力让这一点尽可能清晰,但我确实感激不尽,有点令人困惑。我甚至在标题上遇到了一些麻烦。我为此道歉。如果有任何问题需要澄清,请随时提出任何问题,如果有任何帮助,我将对其进行编辑。
我已经搜索了很长一段时间,但我找不到任何东西。有一段时间我以为我需要使用Pivot,这对我来说是全新的,但现在我没想到。任何帮助将不胜感激,提前谢谢。
我有一张表格,其中显示了在不同位置使用的不同代码和说明。我需要将这些位置合二为一。在我能够做到这一点之前,我需要能够清楚地看到两组数据,给定位置的给定类别中的代码使用的不同描述,以及给定类别中给定类别的描述的不同代码位置,所以我可以得到数据同意。虽然给定代码每个位置每个类别只有一个描述,但给定描述每个位置每个类别可以有多个代码。我只关注在不同地点使用不同代码和类别的情况。出于这些目的,在一个或多个位置相同但未在其他位置使用的代码或描述没有不同。
我需要能够运行一个查询,为给定的类别和代码显示我们按位置的所有描述,包括不使用该代码的空值,其中所有位置的描述都不相同。同样,如果代码没有除null之外的差异,则它不应该在列表中。
我需要能够运行另一个查询,为给定的类别和描述显示所有代码的位置,包括不使用该描述的空值,其中所有位置的代码都不相同请记住,每个位置可能有多个代码。同样如上所述,如果给定类别和描述的代码相同,但未在所有位置使用,则不应返回。
所以,如果我的表有:
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
相同代码不同的描述
CATEGORY CODE aaa_DESCR bbb_DESCR ccc_DESCR ddd_DESCR
Dept 002 NULL NULL Pharmacy Labratory
Dept 003 Clerical Laundry IT Accounting
相同描述不同代码
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
如果有多个列在给定位置有相同描述的多个代码是不可能的,那么也许可以将该位置的所有代码放在由特定字符分隔的一列中,像这样:
CATEGORY DESCR aaa_CODE bbb_CODE ccc_CODE ddd_CODE
Dept Pharmacy 001 001 002 NULL
Job Recepionist 004 004|104 004 004
答案 0 :(得分:2)
您需要的第一步是确定需要格式化的行,因此,对于您要查找相同代码和类别具有多个描述的位置的第一个标准,我会使用EXISTS
:< / p>
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
);
这给出了我们需要格式化的行:
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
然后,如果您对每个类别,代码和位置都有唯一的Desc
,就像我们在这里一样,您可以在PIVOT
函数中使用任意聚合来获得所需的格式:
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;
如果您有多个值,则会变得更加复杂,因此您无法在MAX
内使用PIVOT
。在这里,您需要使用SQL Server's XML extensions to concatenate your similar rows into a single row。
以下使用相同的EXISTS
逻辑来查找正确的行,但不是仅仅选择Code
使用子库来收集(Category, Location, Descr)
特定组合的所有代码并将它们组合成一个记录:
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;
这给出了:
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
获得此格式后,您可以再次使用PIVOT
获取所需的输出。
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 强>
为了完整性,下面是我用于测试的表格:
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');