3

私は大規模な顧客データベースを持っており、顧客テーブルには人と組織との関係があります。人々は複数の組織に属している可能性があります(これにより、組織内での分割が可能になります)。複数の組織を持つ人々は、デフォルトの組織を持っている必要があります。これは通常、どこisDefault = Tで決定されますが、フロントエンドアプリケーションは、isDefault = Fを選択することでデフォルトのアプリケーションを計算することもできますMIN(RowID)

したがって、以下の表でPersonId 3は、デフォルトOrgID11(IsDefault = T)であることがわかります。ただし、PersonID12のデフォルトを見つけるためのクエリを理解する必要があります。すなわち

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の2つを注文し、一番上の結果を取得することで、必要なものを取得できると思います。

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

このロジックを1つのクエリにまとめるのは、かなり複雑です。結果がどこから来たのかを追跡しながら、すべての結果を結合する必要があります。次に、最初の部分からの行数を数え、適切な結果セットの行のみを保持する必要があります。

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

これを試してみてください

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 に答える
0

テーブルの大きさによって異なります。たとえば、rowidに一意のクラスター化インデックスとpersonidがあり、isdefaultにncインデックスがある場合は、2つの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 に答える