简体   繁体   English

SQL选择value ='X'或min值的位置

[英]SQL Select where value = 'X' or min value

I have a large customer database where the customer table has people and their relationship to an organisation. 我有一个庞大的客户数据库,客户表中有人和他们与组织的关系。 People may belong to multiple organisations ( this allows divisions within organisations ). 人们可能属于多个组织( 这允许组织内的部门 )。 People with multiple organisations must have a default organisation, this is usually determined where isDefault = T , however the front end application can also figure the default application where isDefault = F by selecting the MIN(RowID) . 具有多个组织的人员必须具有默认组织,这通常在isDefault = T确定,但是前端应用程序还可以通过选择MIN(RowID)来确定默认应用程序isDefault = F

So in the table below we know PersonId 3 has a default OrgID of 11 (IsDefault = T) However, I need to figure out the query for finding PersonID 12's default. 因此在下表中我们知道PersonId 3的默认OrgID11 (IsDefault = T)但是,我需要找出查找PersonID 12默认值的查询。 ie

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

If 0 rows returned then perform a query like this: 如果返回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

I think you can get what you want by ordering twice, first by whether IsDefault is T or F, then by RowId, and take the top result: 我想你可以通过两次订购得到你想要的东西,首先是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

In MySql server you can do a union with limit 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;

For SQL Server: 对于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;

Didn't tried executing this but expecting this should work. 没试过执行这个但是期望这应该有效。 IsDefault will short circuit the subquery. 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
                           )  
        )

Putting this logic into one query is rather complicated. 将此逻辑放入一个查询中相当复杂。 You have to union all the results together, keeping track of where the result come from. 您必须将所有结果合并在一起,跟踪结果的来源。 Then you have to count how many rows come from the first part, and keep only the rows from the appropriate result set. 然后,您必须计算来自第一部分的行数,并仅保留适当结果集中的行。

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

If you can use TSQL instead of of a single query, then you can just run the first version, check the number of rows in the results, and then decide which result set to take. 如果您可以使用TSQL而不是单个查询,那么您可以只运行第一个版本,检查结果中的行数,然后确定要采用的结果集。

Please try this 请试试这个

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

It depends on how big the table is what are the indexes.If say rowid has unique clustered index and personid and isdefault has a nc index I will use two statemnts. 这取决于表的大小是什么索引。如果说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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM