2014-10-06 100 views
0

我有非常基本的表模式。TSQL消除重复查询

Table A 
TEMPLATE_ID TEMPLATE_NAME 

表A具有以下行

1 Procs 
2 Letter 
3 Retire 
4 Anniversary 
5 Greet 
6 Event 
7 Meeting 
8... etc. 

表B

TEMPLATE_ID VALUE 

表B具有TEMPLATE_ID 100K +行连接两个表。

现在,执行人员需要表A中2​​0个类型为1-5的记录样本。我可以做一些基本的......这与我在TSQL方面的速度有关。

SELECT TOP(20) B.VALUE FROM TableB 
JOIN TableA ON 
B.TEMPLATE_ID = A.TEMPLATE_ID 
AND TableA.TEMPLATE_NAME IN ('Procs', 'Letter'...) 

但是,这不是很正确,因为我结束了20行......换句话说,我期待100行。每个20个。

这是可以使用分区的区域之一。我可以看到如何将TableB分解为每个模板(tableA)的分区,但我不知道如何将其限制为20行。

好的,我可以从每个分区切入Excel 20行......我也可以写5个非常基本的查询......但这是一种学术......提高我的知识追求。

所以澄清。来自每个第一个r模板类型的20条记录。

TIA

+0

感谢编辑@guildbounty ......我没有注意到的格式有多么糟糕横空出世。 – GPGVM 2014-10-06 19:57:44

回答

4

您可以使用ROW_NUMBER和分区基础上,TEMPLATE_NAME的数据,只有20从每个分区

SELECT * FROM 
(
SELECT B.VALUE, 
     ROW_NUMBER() OVER (PARTITION BY TableA.TEMPLATE_NAME ORDER BY (select NULL)) as seq 
FROM 
TableB 
JOIN TableA ON 
B.TEMPLATE_ID = A.TEMPLATE_ID 
) T 
where T.seq <=20 
order by B.VALUE 
+0

ROW_NUMBER ......这就是我所缺少的。谢谢。 – GPGVM 2014-10-06 20:08:52

+0

Type 1-5如何? – Paparazzi 2014-10-06 20:12:11

-1
SELECT * FROM 
(SELECT B.VALUE, TableA.TEMPLATE_NAME 
     ROW_NUMBER() OVER (PARTITION BY A.TEMPLATE_ID ORDER BY NEWID()) as row 
    FROM TableB 
    JOIN TableA 
     ON A.TEMPLATE_ID = B.TEMPLATE_ID 
    AND A.TEMPLATE_ID <= 5 
) T 
where T.row <= 20 
order by B.VALUE 
+0

倒票护理回应。与接受的答案同时发布。被接受的答案没有“第一个r模板类型”。 – Paparazzi 2014-11-06 13:22:08

0

你能尝试返回?

SELECT B.VALUE 
FROM 
(
    SELECT TEMPLATE_ID,VALUE, DENSE_RANK () OVER (PARTITION BY TEMPLATE_ID ORDER BY VALUE DESC) AS RANK_NO 
    FROM TABLE_B 
) B INNER JOIN TABLE_A A ON (A.TEMPLATE_ID = B.TEMPLATE_ID) 
WHERE A.TEMPLATE_NAME IN ('Procs', 'Letter'...) 
AND B.RANK_NO <= 20 
; 
0

您使用排名功能。你的第一个分区的数据,命令每个分区和应用分级功能:

select seq = row_number() over (
       partition by table_catalog , table_schema , table_name 
       order by column_name 
       ) , 
     * 
from information_schema.COLUMNS 

上面的代码分区中的行information_schame.COLUMNS在它们所属的完全合格的表/视图名称。然后按字母顺序对每个分区进行排序,并给出row_number()

然后被包装在另一个使用它的选择中。此代码会将第一个3列基于列的系统每个表,并提供了一些关于它的信息:

select t.table_name , 
     t.table_schema , 
     t.table_name , 
     t.table_type , 
     c.seq , 
     c.ordinal_position , 
     c.COLUMN_NAME , 
     data_type = c.data_type + coalesce('('+convert(varchar,c.character_maximum_length)+')','') 
       + case c.is_nullable when 'yes' then ' is  null' else ' is not null' end 
from information_schema.tables t 
join (select seq = row_number() over (
         partition by table_catalog , table_schema , table_name 
         order by column_name 
        ) , 
       * 
     from information_schema.COLUMNS 
    ) c on c.table_catalog = t.table_catalog 
     and c.table_schema = t.table_schema 
     and c.table_name = t.table_name 
where c.seq <= 3 
order by t.table_catalog , 
     t.table_schema , 
     t.table_name , 
     c.seq