3

我有一个大型客户数据库,其中客户表包含人员及其与组织的关系。人们可能属于多个组织(这允许组织内的划分)。拥有多个组织的人必须有一个默认组织,这通常由 where 确定isDefault = T,但是前端应用程序也可以isDefault = F通过选择MIN(RowID).

所以在下表中,我们知道PersonId 3有一个默认值OrgID( 11IsDefault = T) 但是,我需要弄清楚查找 PersonID 12 的默认值的查询。IE

Select orgId as default from myTable
where personID = 12
and isDefault = 'T'

如果返回 0 行,则执行如下查询:

Select orgId as default from myTable
where personID = 12
and 
RowId in (select Min(rowId) 
from myTable 
where PersonId = 12)


RowID | PersonID  | OrgId  |  isDefault
1     |    12     |   14   |     F
2     |    12     |   17   |     F
3     |    3      |   11   |     T
4     |    3      |   14   |     F
4

6 回答 6

2

我认为您可以通过订购两次来获得您想要的东西,首先是 IsDefault 是 T 还是 F,然后是 RowId,然后获得最高结果:

SELECT TOP 1 OrgId as [Default]
FROM MyTable
WHERE PersonId = 12
ORDER BY
    CASE WHEN IsDefault = 'T' THEN 0 ELSE 1 END,
    RowId
于 2012-07-14T01:39:35.477 回答
1

没有尝试执行此操作,但希望这应该有效。IsDefault 将使子查询短路。

  Select orgId as default from myTable o
   where personID = 12 
       and  
       ( IsDefault = 'T' OR
                   RowId = (select Min(rowId)  
                               from myTable i
                             where i.PersonId = o.PersonId
                           )  
        )
于 2012-07-14T02:02:40.327 回答
1

在 MySql 服务器中,您可以使用限制 1 进行联合:

SELECT OrgId AS `default`
FROM (
    SELECT OrgId FROM MyTable
    WHERE PersonID = 12
    and isDefault = 'T'

    UNION

    SELECT OrgId FROM MyTable
    WHERE PersonId = 12
    AND RowId in (
        SELECT MIN(RowId)
        FROM MyTable
        WHERE PersonId = 12
    )
) SomeName LIMIT 1;

对于 SQL Server:

SELECT TOP 1 OrgId AS [default]
FROM (
    SELECT OrgId FROM MyTable
    WHERE PersonID = 12
    and isDefault = 'T'

    UNION

    SELECT OrgId FROM MyTable
    WHERE PersonId = 12
    AND RowId in (
        SELECT MIN(RowId)
        FROM MyTable
        WHERE PersonId = 12
    )
) SomeName;
于 2012-07-14T01:37:39.293 回答
0

将此逻辑放入一个查询中是相当复杂的。您必须将所有结果合并在一起,跟踪结果的来源。然后你必须计算有多少行来自第一部分,并且只保留相应结果集中的行。

select orgid, mytable
from (select t.*, sum(which) over (partition by null) as whichcnt
      from ((Select 1 as which, orgId as default
             from myTable
             where personID = 12 and
                   isDefault = 'T'
            )
            union all
           (Select 0 as which, orgId as default
            from myTable
            where personID = 12 and 
                  RowId in (select Min(rowId) from myTable where PersonId = 12)
           )
          ) t
     ) t
where whichcnt > 0 and which = 1 or whichcnt = 0

如果您可以使用 TSQL 而不是单个查询,那么您可以只运行第一个版本,检查结果中的行数,然后决定采用哪个结果集。

于 2012-07-14T01:34:20.050 回答
0

这取决于表的大小是什么索引。如果说 rowid 有唯一的聚集索引和 personid 并且 isdefault 有一个 nc 索引,我将使用两个 statemnts。

 declare @orgid int = null
 select @orgid =orgid from table where personid = 12 and isdefault = 'T'
 if (orgid  is null)
 begin
 select @orgid = orgid 
 from mytable
 where rowid = (
 select min(rowid)from table where personid = 12 and isdefault = 'F'
 )
 end
于 2012-07-14T07:02:38.507 回答
0

请试试这个

select PersonID ,OrgID from mytable where isDefault='T'
union all

select personID,min(OrgID) [default]
from myTable P
where  not exists 
(select * from mytable C where P.PersonID=C.PersonID and C.isDefault='T')
group by personID
于 2012-07-14T03:56:54.647 回答