TSQL消除重复查询

时间:2014-10-06 19:53:22

标签: sql-server 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有100K +行,TEMPLATE_ID连接两个表。

现在,高管想要从表A中获取20个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

4 个答案:

答案 0 :(得分: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

答案 1 :(得分: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
;

答案 2 :(得分: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

答案 3 :(得分:-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