Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 按列然后按空选择数据_Sql_Sql Server - Fatal编程技术网

Sql 按列然后按空选择数据

Sql 按列然后按空选择数据,sql,sql-server,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_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,否则使用空行

有没有比这更好的方法呢

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)

我想你在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)

第一次合并将首先通过ID查看。。。如果没有,请转到用户。如果仍然找不到用户,则默认情况下,最终ID为NULL

第二列没有case/when,因此您可以类似地标识找到它的模式,如果没有,则标识为NULL

@variables sqlvars将创建一个单行结果,因此它是联接的基础,然后通过在各自的ID上执行左联接,将始终至少返回1行,以左联接每个联接容量中的另一个表

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

没有得到你想要的。您说您有1个表,但您的查询显示3该表称为tbl\u实体\u列\u详细信息其他两个是cte,并且您的不存在检查不会执行您想要的操作。如果Company\u Filter没有行,则第二个查询将返回User\u Filter中的所有行。no它只返回由于where谓词而导致的用户Id等于传递的值的行。如果Company_Filter中有任何行,则EXISTS工件将不会返回行。从本质上讲,用户标识传入的内容,而公司过滤器中没有行