1

これは SQL スペシャリストへの質問です。

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}

目標を達成するには、クエリをどのように修正すればよいですか?

簡単な解決策があるとは思えない二次的な質問があります。

列で説明されているように、相対レコードには 2 つの種類があります[IsImportant]

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

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

4

1 に答える 1

5

編集

これは要件の正しい言い換えですか?

[myTable] には 3 つの関連フィールドがあります...

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

    1. 10 個以下のマスター レコードを返す
    2. マスター レコードごとに、4 つ以下の相対レコードを返す
    3. 4 つの相対レコードのうち、返される IsImportant レコードは 1 つだけです
    4. 親族が 4 つ未満のマスターをスキップします (すべての IsImportant を 1 つとして扱います)。

質問:
- マスターに 3 つの相対レコードがあり、どれも isImportant でない場合、スキップしますか?
- マスターに 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
于 2012-04-26T15:03:14.023 に答える