2012-04-26 49 views
1

这是一个SQL专家的问题!如何短语2阶循环T-SQL SELECT查询?

我正在使用SQL SERVER 2008 R2 Express。

我有一张名为[myTable]的表格由两种类型的记录组成。

第一类记录是主记录,第二类记录是[Relative]记录。

每个主记录可能有多个相关记录。

我想SLELECT TOP 10 * FROM [myTable]主记录,和联合子记录像 [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]说明。

有没有办法确保每个主记录只能选择1个重要的相对记录?

如果有少于4个相对记录的话,有没有办法跳过主记录,而只有其中一个记录很重要?

+0

您可以包括一些样本输入数据,长着什么你想要的输出是什么?你最后的改变让我感到困惑。 – MatBailie 2012-04-26 15:11:02

回答

5

编辑

这是您的要求正确的释义?

[myTable的]具有3个相关领域...

  • PKID:对于每一行
  • 相对唯一标识符:该行的父的PKID(0,如果该行没有父[AKA - 主])
  • IsImportant:0/1标志

    1. 返回不超过10的主记录
    2. 对于每个MAS之三的记录,返回不超过4个相对记录
    3. 的4条相记录,返回不超过1个IsImportant记录
    4. 跳过某个具有小于4名亲属的任何主机(对待所有IsImportant刚刚1)

问题:
- 如果主人有3个相对记录,并且他们都不是isImportant,还跳过?
- 如果主人有4个相对记录,且1个以上是isImportant,仍然跳过?

最佳猜测答案...

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