我需要为另一张表中的每个匹配行选择一个列。听起来很简单,但有一点曲折。
我下面的代码可以正常工作,并且正是我想要的。但是我必须硬编码到要查找哪些部门的查询中。我希望它根据在“部门”表中找到的部门代码进行子选择,而无需我对该公司可能存在的每个可能部门进行硬编码。
我需要根据DepartmentsStatus表中定义的公司存在的部门来从DepartmentStatus中选择匹配的部门状态。
我怀疑它是数据透视表,但它们略高于我的水平。
(公司表)
Company_ID Company_Name
-------------------------
1 Home Office
2 Stanton Office
3 NYC Office
(部门表)
CompanyID Department_Code
----------------------------
1 Sales
1 Inventory
1 Retail
1 Maint
2 OtherDept
2 ThatDept
2 BobsDept
(部门状态表)
Company_ID Department StatusCode
-----------------------------------------
1 Sales InReview
1 Inventory InReview
1 Retail Ready
1 Maint Done
2 OtherDept InReview
2 ThatDept Research
2 BobsDept InReview
注意:即使Company_ID + Department上有唯一索引,我也使用“ TOP 1”,因此匹配的行不会超过一个。
因此,对于Company_ID = 1:
select Company_ID,
(select top 1 StatusCode from DepartmentStatus ds where ds.Company_ID = cm.Company_ID and ds.Department='Sales') as SalesStatus
(select top 1 StatusCode from DepartmentStatus ds where ds.Company_ID = cm.Company_ID and ds.Department='Inventory') as InvStatus
(select top 1 StatusCode from DepartmentStatus ds where ds.Company_ID = cm.Company_ID and ds.Department='Retail') as RetailStatus
(select top 1 StatusCode from DepartmentStatus ds where ds.Company_ID = cm.Company_ID and ds.Department='Main') as MaintStatus
from Company cm
Where cm.CompanyID=1
结果:
Company_ID SalesStatus InvStatus RetailStatus MaintStatus
--------------- --------------- ---------- ------------- ------------
1 InReview InReview Ready Done
或者,对于CompanyID = 2:
select Company_ID,
(select top 1 StatusCode from DepartmentStatus ds where ds.CompanyID = cm.Company_ID and ds.Department='OtherDept') as OtherDeptStatus
(select top 1 StatusCode from DepartmentStatus ds where ds.CompanyID = cm.Company_ID and ds.Department='ThatDept') as ThatDeptStatus
(select top 1 StatusCode from DepartmentStatus ds where ds.CompanyID = cm.Company_ID and ds.Department='BobsDept') as BobsDeptStatus
from Company cm
Where cm.CompanyID=2
结果:
Company_ID OtherDeptStatus ThatDeptStatus BobsDeptStatus
---------- ---------------- -------------- --------------
2 InReview Research InReview
因此,对于公司1,我需要获取部门销售,库存,零售和维护的状态。 但是对于公司2,我需要获得Departments OtherDept,ThatDept和BobsDept的状态。
我认为描述我要执行的步骤是:
问题是,我不知道(在查询时)每个公司都有哪些部门,因此我需要根据每个公司实际存在的部门进行子选择。
还有其他一些S.O.答案已经很接近我的要求,建议使用JOIN来完成此任务,但是,它们都假定您在编写join语句时就已经知道要查询的值。
我正在寻找解决此问题的方法,而不仅仅是对当前尝试的更正。如果您对如何完成此操作完全有更好的想法,我很乐意看到它。
答案 0 :(得分:1)
您似乎正在寻找条件聚合。使用此技术,您的查询可以简化如下,以避免需要多个内联子查询:
select Company_ID,
max(case when ds.Department='Sales' then ds.StatusCode end) as SalesStatus,
max(case when ds.Department='Inventory' then ds.StatusCode end) as InvStatus,
max(case when ds.Department='Retail' then ds.StatusCode end) as RetailStatus,
max(case when ds.Department='Main' then ds.StatusCode end) as MaintStatus
from
Company cm
inner join DepartmentStatus ds on ds.Company_ID = cm.Company_ID
Where cm.CompanyID=1
group by cm.CompanyID
答案 1 :(得分:0)
这是我(未尝尝)穴居人解决问题的方法。 您唯一需要事先了解的是公司中拥有最多部门的几个不同部门。
DROP TABLE IF EXISTS Iddepartmentstatus;
DECLARE @Result TABLE(
Companyid INT,
Department1 NVARCHAR(MAX),
Department2 NVARCHAR(MAX),
Department3 NVARCHAR(MAX),
Department4 NVARCHAR(MAX),
Department5 NVARCHAR(MAX));
CREATE TABLE Iddepartmentstatus(
Num INT IDENTITY(1, 1),
Department NVARCHAR(MAX),
Statuscode NVARCHAR(MAX));
DECLARE @IDCompany TABLE(
Num INT IDENTITY(1, 1),
Companyid INT,
Companyname NVARCHAR(MAX));
INSERT INTO @IDCompany (Companyid,
Companyname)
SELECT Company_Id,
Company_Name
FROM Company;
DECLARE @Departmentcount INT = 0,
@Departmentstatuscount INT = 0,
@Companycount INT = 0;
WHILE @Companycount <=
(
SELECT MAX(Num)
FROM @IDCompany)
BEGIN
INSERT INTO Iddepartmentstatus (Department,
Statuscode)
SELECT Department,
Statuscode
FROM Departmentstatus
WHERE Company_Id = @Companycount;
INSERT INTO @Result (Companyid)
SELECT @Companycount AS T;
INSERT INTO @Result (Department1)
SELECT IIF(1 <=
(
SELECT MAX(Num)
FROM @IDCompany), Department + ': ' + Departmentstatus, NULL)
FROM Iddepartmentstatus
WHERE Num = 1;
INSERT INTO @Result (Department2)
SELECT IIF(2 <=
(
SELECT MAX(Num)
FROM @IDCompany), Department + ': ' + Departmentstatus, NULL)
FROM Iddepartmentstatus
WHERE Num = 2;
INSERT INTO @Result (Department3)
SELECT IIF(3 <=
(
SELECT MAX(Num)
FROM @IDCompany), Department + ': ' + Departmentstatus, NULL)
FROM Iddepartmentstatus
WHERE Num = 3;
INSERT INTO @Result (Department4)
SELECT IIF(4 <=
(
SELECT MAX(Num)
FROM @IDCompany), Department + ': ' + Departmentstatus, NULL)
FROM Iddepartmentstatus
WHERE Num = 4;
INSERT INTO @Result (Department5)
SELECT IIF(5 <=
(
SELECT MAX(Num)
FROM @IDCompany), Department + ': ' + Departmentstatus, NULL)
FROM Iddepartmentstatus
WHERE Num = 5;
TRUNCATE TABLE Iddepartmentstatus;
SET @Companycount = @Companycount + 1;
END;
DROP TABLE IF EXISTS Iddepartmentstatus;