2012-04-26 5 views
1

これはSQLの専門家にとっての質問です!2段ループT-SQL SELECTクエリはどのようにフレーズしますか?

私はSQL Server 2008 R2 Expressを使用しています。

[myTable]という名前のテーブルが2種類のレコードで構成されています。

第1のタイプのレコードはマスターレコードであり、第2のタイプは[Relative]レコードです。

各マスタレコードには、複数の関連レコードが含まれている場合があります。

私はしSLELECT TOP 10 * FROM [myTable]マスタレコード、およびそれぞれのSELECT TOP 4[Relative]の記録のような労働組合のサブレコードをしたいと思います。

各レコードには[PKID] NO NULL IDENTITY(1,1) PRIMARY KEY CLUSTEREDの列があります。私は私の目標を達成するために、クエリを修正する必要がありますどのように

SELECT TOP 10 * FROM [myTable] WHERE [Relative]=0 
UNION 
For each (SELECT TOP 10 [PKID] as Master, * FROM [myTable] WHERE [Relative]=0) 
{SELECT TOP 4 * FROM [myTable] WHERE [Relative] = Master} 

私はそのような何かが必要だと思いますか?コラム[IsImportant]で説明したよう

相対レコードは2種類があります:

は、私はそれのためのシンプルなソリューションがあります疑う二疑問を持っています。

マスターレコードごとに重要な相対レコードが1つだけ選択されるようにする方法はありますか?

1つしか重要ではないが相対レコードが4つ未満の場合、マスターレコードをスキップする方法はありますか?

+0

あなたは長い間、あなたが出力になりたいと思い何をして、いくつかのサンプルの入力データが含まれてもらえますか?あなたの最後の変更は私を少し混乱させました。 – MatBailie

答えて

5

EDIT

これはあなたの要件の正しい言い換えますか?

[MYTABLE]は3つの関連フィールド...

  • PKID:各行
  • 相対の一意の識別子:行の親のPKID(0行に親がない場合は[AKA - マスター】)
  • IsImportant:0/1フラグ

    1. 戻りせいぜい10のマスタレコード各MASについて
    2. TERレコード、せいぜい4つの相対レコードを4つの相対レコードの
    3. を返さないが、4未満の親族(ちょうど1としてすべてIsImportantの治療)
  • を持つ任意のマスターをスキップわずか1 IsImportantレコード
  • を返します

質問:
- マスターに3つの相対レコードがあり、どれも重要でない場合は、まだスキップしますか?
- マスターに4つの相対レコードがあり、1以上が重要である場合は、スキップしますか?

ベスト推測の答え...

WITH 
    master_metadata 
AS 
(
    SELECT 
    relative   AS MasterID, 
    COUNT(*)   AS Relatives, 
    SUM(isImportant) AS IsImportantRelatives 
    FROM 
    [myTable] 
    WHERE 
    relative <> 0 
    GROUP BY 
    relative 
    HAVING 
    COUNT(*) - SUM(isImportant) + MAX(isImportant) >= 4 
) 
, 
    master 
AS 
(
    SELECT TOP 10 
    NULL AS sequence_id, 
    [myTable].*, 
    [master_metadata].Relatives, 
    [master_metadata].IsImportantRelatives 
    FROM 
    [myTable] 
    INNER JOIN 
    [master_metadata] 
     ON [master_metadata].MasterID = [myTable].PKID 
    ORDER BY 
    [myTable].Selector 
) 
, 
    relative 
AS 
(
    SELECT 
    ROW_NUMBER() OVER (PARTITION BY relative, IsImportant ORDER BY Selector) AS sequence_id, 
    * 
    FROM 
    [myTable] 
) 
, 
    data 
AS 
(
    SELECT 
    PKID AS MasterID, 
    * 
    FROM 
    [master] 

    UNION ALL 

    SELECT 
    [master].PKID AS MasterID, 
    [relative].*, Relatives, IsImportantRelatives 
    FROM 
    [master] 
    INNER JOIN 
    [relative] 
     ON ([relative].relative = [master].PKID) 
     AND ( ([relative].isImportant = 1 AND [relative].sequence_id = 1) 
      OR ([relative].isImportant = 0 AND [relative].sequence_id <= 3) 
      OR ([relative].isImportant = 0 AND [relative].sequence_id = 4 AND [master].IsImportantRelatives = 0) 
     ) 
) 

SELECT 
    * 
FROM 
    [data] 
ORDER BY 
    MasterID, 
    CASE WHEN MasterID = PKID THEN 0 ELSE 1 END, 
    IsImportant DESC, 
    relative 
関連する問題