簡體   English   中英

Select 一個表中的行,基於另一個表中的列值?

[英]Select rows in one table, based on column values in another table?

我需要為另一個表中的每個匹配行 select 一列。 聽起來很簡單,但有一個轉折點。

  • 我有一張包含公司 ID 並定義公司的表。
  • 我有另一個表,它定義了這些公司的部門。
  • 我有第三個表,其中包含各種部門狀態代碼。

我在下面的代碼工作得很好,這正是我想要它做的。 但是我必須硬編碼到要查找的部門的查詢中。 我希望它根據在“部門”表中找到的部門代碼進行子選擇,而不是要求我對該公司可能存在的每個可能的部門進行硬編碼。

我需要 select 根據 DepartmentsStatus 表中定義的公司存在的部門,從 DepartmentStatus 匹配部門狀態。

我懷疑這是一張 pivot 表,但它們比我的水平高一點。

(公司表)

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

注意:我使用“TOP 1”,即使 Company_ID+Department 上有唯一索引,所以匹配的行永遠不會超過一個。

因此,對於 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,我需要 go 獲取部門銷售、庫存、零售和維護的狀態。 但是對於公司 2,我需要獲取 Departments OtherDept、ThatDept 和 BobsDept 的狀態。

我認為描述我正在嘗試做的步驟是:

  1. 從部門表中獲取公司 1 的部門列表。
  2. 對於步驟 1 中的每個部門,查詢 DepartmentStatus 表中的 Department 是否等於該部門。 對於公司 1,查詢獲取部門“銷售、庫存、零售和維護”的 StatusCode 對於公司 2,查詢獲取部門“OtherDept、thatDept 和 BobsDept”的 StatusCode。 等等等等

問題是,我不知道提前(在查詢時)每個公司存在哪些部門,所以我需要根據每個公司實際存在的部門進行子選擇。

已經有一些其他 SO 答案與我所要求的很接近,建議使用 JOIN 來完成此操作,但是,它們都假設您在編寫 join 語句時提前知道要查詢的值.

我正在尋找解決此問題的方法,而不僅僅是對我當前嘗試的更正。 如果您對如何實現這一點有更好的想法,我很樂意看到它。

您似乎正在尋找條件聚合。 使用這種技術,您的查詢可以簡化如下,以避免需要多個內聯子查詢:

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 

這將是我(未經測試的)穴居人解決問題的方法。 您唯一需要提前知道的是,您所在的公司有多少個不同的部門,部門最多。

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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM