按列选择数据,然后按null

时间:2014-09-08 16:11:21

标签: sql sql-server

我有一张包含以下数据的表

User_Id CpyId   SortOrder ColName
NULL    NULL    1         User_Id
NULL    NULL    2         User_Code
NULL    NULL    3         User_Name
NULL    NULL    4         User_Type_Descr
100001  NULL    1         User_Id
100001  NULL    2         User_Name
100001  NULL    3         User_Type_Descr
100001  NULL    4         User_Code
NULL    1       1         User_Id
NULL    1       2         User_Other_Name
NULL    1       3         User_Type_Descr
NULL    1       4         User_Code

我想优先选择CpyId,如果匹配CpyId输入,如果不匹配UserId,则使用NULL行

有没有更好的方法呢?

declare @UserId int, @CpyID int

select @UserId = 100002, @CpyId =1;

With Company_Filter As 
(select * from tbl_Entity_Column_Details where Company_Id = @CpyId),
 User_Filter As 
(select * from tbl_Entity_Column_Details where User_Id = @UserId)

select * from Company_Filter
union
select * from User_Filter where not exists (select * from Company_Filter)
union
select * from tbl_Entity_Column_Details where User_Id is null and Company_ID is null 
and not exists (select * from Company_Filter)
and not exists (select * from User_Filter)

2 个答案:

答案 0 :(得分:0)

我认为你的where子句中的意思是“CpyId”而不是“CompanyId”。 所以我这样做的方法是获得所有可能的结果并对它们进行排名。 然后只选择最低等级的结果。

--Declare UserId and CpyId
declare @UserId int = 100001
declare @CpyID int = 1;

--Select all possible results and rank
WITH subryUnion 
AS (

--Select hits by CpyId, Rank 1
SELECT *, 
    1 AS Ranking,
    'Hit by CpyId' Descr
FROM tbl_Entity_Column_Details
WHERE CpyId = @CpyId

UNION ALL

--Select hits by User_Id, Rank 2
SELECT *, 
    2 AS Ranking,
    'Hit by User_Id' Descr
FROM tbl_Entity_Column_Details
WHERE User_Id = @UserId

UNION ALL

--Select no hits by CpyID or User_Id, Rank 3
SELECT *,
    3 AS Ranking,
    'Not hit by CpyId or User_Id' Descr
FROM tbl_Entity_Column_Details
WHERE COALESCE(CpyId,User_Id) IS NULL

)

SELECT *
FROM subryUnion
--Show only the minimum ranked results
WHERE Ranking = (SELECT MIN(Ranking) FROM subryUnion)

答案 1 :(得分:0)

第一个COALESCE()将首先按ID查找...如果没有,请转到USER。如果仍未找到User,则默认情况下最终ID为NULL。

SECOND列是case / when所以你可以类似地识别它被找到的WHICH模式(或NULL)。

(@variables)sqlvars将创建单行结果,因此它是JOIN的基础,然后通过对各个ID执行左连接,将始终返回1行至少LEFT-JOIN每个中的另一个表加入能力。

SELECT
      COALESCE( byID.CpyID, byUser.User_ID ) as WhichID,
      CASE when byID.CpyID IS NOT NULL then "ID"
           when byUser.User_ID IS NOT NULL then "USER"
           ELSE null end as WhichID, "NULL"      
   from 
      ( select @UserId = 100002, @CpyId =1 ) sqlvars,
         LEFT JOIN tbl_Entity_Column_Details byID
            ON @CpyID = byID.CpyID

         LEFT JOIN tbl_Entity_Column_Details byUser
            ON @UserID = byUser.User_ID