3

私は2つのテーブルを持っています: PPC(列IDによって結合されたマスター/詳細)

Table P:
Id integer
Name varchar(12)

Table PC:
Id   integer
Code varchar(12)
Val  number

次の同時条件を満たすPからすべての名前を取得したい:

  • とPCを持ってPC.Code='A'いるVal>100

  • と別のPCを持っ PC.Code='B'ているVal>80

要約すると、詳細が両方の条件に準拠しているP.Nameにのみ関心があります。INTERSECTに頼らずに選択する方法はありますか?

INTERSECTクエリは次のとおりです。

Select P.Name 
  from P, PC
 where P.Id=PC.Id
   and PC.Code='A' and Val>100
INTERSECT
Select P.Name 
  from P, PC
 where P.Id=PC.Id
   and PC.Code='B' and Val>80

(関心は、パフォーマンスをチェックし、Accessでクエリを実行できるようにすることです)

4

6 に答える 6

1

パフォーマンスがどうなっているのかわからない..試してみてください..

SELECT P.Name 
  FROM P
  INNER JOIN PC AS a ON P.Id=a.Id and a.Cod='A' and a.Val>100
  INNER JOIN PC AS b ON P.Id=b.Id and a.Cod='B' and a.Val>80
于 2012-01-23T16:31:51.323 に答える
1

関係的に同等の(つまり、重複する行を削除する)代替アプローチを次に示します。

SELECT P.Name 
  FROM P
 WHERE EXISTS (
               SELECT * 
                 FROM PC
                WHERE P.Id = PC.Id
                      AND PC.Code ='A' 
                      AND PC.Val > 100
              )
      AND EXISTS (
                  SELECT * 
                    FROM PC
                   WHERE P.Id = PC.Id
                         AND PC.Code ='B' 
                         AND PC.Val > 80
                 );

意味的に同等である(重複する行を返す可能性があるという点で)いくつかの選択肢を次に示します。

SELECT P.Name 
  FROM P, PC
 WHERE P.Id = PC.Id
       AND PC.Code ='A' 
       AND PC.Val > 100
       AND P.Name IN (
                      SELECT P1.Name 
                        FROM P AS P1, PC AS PC1
                       WHERE P1.Id = PC1.Id
                         AND PC1.Code = 'B' 
                             AND PC1.Val > 80
                     );
SELECT P.Name 
  FROM P, PC
 WHERE P.Id = PC.Id
       AND PC.Code ='A' 
       AND PC.Val > 100
       AND P.Name = ANY (
                         SELECT P1.Name 
                           FROM P AS P1, PC AS PC1
                          WHERE P1.Id = PC1.Id
                            AND PC1.Code = 'B' 
                                AND PC1.Val > 80
                        );
于 2012-01-24T08:45:36.487 に答える
0
SELECT P.Name
  FROM P
  JOIN PC AS P1 ON P.Id = P1.Id AND P1.Cod = 'A' AND P1.Val > 100
  JOIN PC AS P2 ON P.Id = P2.Id AND P2.Cod = 'B' AND P2.Val >  80

テーブルエイリアスP1およびP2を使用すると、3方向結合を実行できます。ただし、これは完全な自己参加ではありません。今回ではない。

于 2012-01-23T16:29:30.350 に答える
0
Select p.Name
from P p
inner join PC pc1 on p.Id = pc1.Id and pc1.Cod = 'A' and pc1.Val > 100
inner join PC pc2 on p.Id = pc2.Id and pc2.Cod = 'B' and pc2.Val > 80
于 2012-01-23T16:29:59.923 に答える
0
Select P.Name 
  from P, PC
 where P.Id=PC.Id
   and PC.Cod='A' and Val>100
   and exists (Select 1 From PC Where Id = P.Id and Cod = 'B' and Val > 80)
于 2012-01-23T16:31:24.240 に答える
0

実際にはこれを使用しませんが、代替手段です...

SELECT P.Name
FROM   P
       JOIN PC
         ON P.Id = PC.Id
WHERE  PC.Cod IN ( 'A', 'B' )
       AND Val > 80
GROUP  BY P.Id,
          P.Name
 HAVING MAX(CASE WHEN PC.Cod='A' and Val>100 THEN 1 END) = 1 
 AND MAX(CASE WHEN PC.Cod='B' and Val>80 THEN 1 END) = 1 

または、Microsoft Accessの場合、having句は次のようになります。

 HAVING MAX(IIf(PC.Cod='A' and Val>100, 1, 0)) = 1 
 AND MAX(IIf(PC.Cod='B' and Val>80, 1, 0)) = 1 
于 2012-01-23T16:32:04.007 に答える