WHERE子句中的SQL查询WITH CASE

时间:2015-07-16 15:36:49

标签: sql sql-server tsql stored-procedures

我必须为实体返回行。

一个实体可以拥有多个办公地址,其中一个办公地址可以作为总部。

我有一个表格,我显示所有实体,但我只能显示一个实体的一个地址。

所以我必须选择至少一个地址

  1. 总部致辞
    1. 选择前1位地址

      SELECT *
      FROM Entity
      LEFT JOIN ......
      WHERE
         [INSERT  CODE TO GET ADDRESS]
      

2 个答案:

答案 0 :(得分:2)

在不了解您的架构的情况下,我会尝试让您大致了解如何实现您的目标。

CREATE TABLE #tempAddress (
    ID int not null,
    CompanyID int not null,
    Address varchar(50),
    IsHQ bit not null
)

CREATE TABLE #tempCompany (
    ID int not null,
    Name varchar(50)
)

INSERT INTO #tempAddress (ID, CompanyID, Address, IsHQ)
SELECT 1, 1, 'Address 1', 1
UNION ALL
SELECT 2, 1, 'Address 2', 0
UNION ALL
SELECT 3, 1, 'Address 3', 0
UNION ALL
SELECT 4, 1, 'Address 4', 0
UNION ALL
SELECT 5, 2, 'Address 5', 1
UNION ALL
SELECT 6, 2, 'Address 6', 0
UNION ALL
SELECT 7, 3, 'Address 7', 0

INSERT INTO #tempCompany (ID, Name)
SELECT 1, 'Company 1'
UNION ALL
SELECT 2, 'Company 2'
UNION ALL
SELECT 3, 'Company 3'


;with addr as (
    select *, ROW_NUMBER() OVER (PARTITION BY CompanyID ORDER BY CASE WHEN IsHQ=1 THEN 0 ELSE ID END) AS RowNum
    from #tempAddress
)
SELECT * 
FROM #tempCompany C
    LEFT JOIN addr A ON C.ID = A.CompanyID AND A.RowNum=1

DROP Table #tempAddress
DROP Table #tempCompany

结果:

ID  Name             AddressID  CompanyID   Address      IsHQ   RowNum
1   Company 1        1          1           Address 1    1      1
2   Company 2        5          2           Address 5    1      1
3   Company 3        7          3           Address 7    0      1

在示例中,公司1和2有总部,公司3没有。

如您所见,我使用PARTITION BY对地址进行编号,将总部地址显示在可能存在的任何其他地址之上。然后将结果与公司表连接,只选择前1行。

这里Sql Fiddle,由Juan Carlos Oropeza提供。

答案 1 :(得分:0)

使用ROWNUMBER()...

的另一种方法
Declare @TheOnesIWantTable Table (AddressID int, CompanyID int)

--One Address Per Company With HQ

INSERT @TheOnesIWantTable (AddressID,CompanyID)
Select [AddressID], [CompanyID] From [AddressTable] Where [HQ] = 1

--One Address Per Company NOT With HQ

INSERT @TheOnesIWantTable (AddressID,CompanyID)
Select MAX(AddressID), CompanyID From [AddressTable] WHERE [CompanyID] NOT IN
   (Select [CompanyID] From [AddressTable] Where [HQ] = 1)

@TheOnesIWantTable现在拥有您在最终结果集中所需的所有(且唯一)地址ID。现在你可以在JOIN中使用它了:

SELECT
   C.*,
   A.*
FROM
   CompanyTable C

   INNER JOIN AddressTable A
   ON C.CompanyID = A.CompanyID

   INNER JOIN @TheOnesIWantTable T
   ON A.AddressID = T.AddressID