1

我不完全确定如何表达我正在寻找的东西,这使得搜索变得困难。但我想做的是为每个不同的列匹配返回一条记录

表结构:

ItemHolderId Name
------------ --------------------------------------------------
1            Holder A
2            Holder B


ItemId      Data                                               ItemHolderId
----------- -------------------------------------------------- ------------
1           Item A                                             1
2           Item B                                             1
3           Item C                                             1
4           Item D                                             1
5           Item E                                             2
6           Item F                                             2
7           Item G                                             2

我希望为每个物品持有者 ID 选择一个物品。例如,它只会选择项目 A 和项目 E。对于每个匹配的列,顺序无关紧要。我希望我以明智的方式解释这一点。

谢谢你的时间。

4

3 回答 3

2

如果您使用的是 SQL Server 2005及更高版本(您在这方面不够具体),则一种方法是使用 CTE(通用表表达式)。

使用此 CTE,您可以按某些条件(即您的)对数据进行分区,ItemHolderId并让 SQL Server 为每个分区从 1 开始为所有行编号,并按其他一些条件排序(您需要一些条件 - 您使用的是给你)。

所以尝试这样的事情:

;WITH PartitionedComponents AS
(
   SELECT 
       ih.ItemHolderID, ih.Name, d.Data,
       ROW_NUMBER() OVER(PARTITION BY ih.ItemHolderID ORDER BY d.Data DESC) AS 'RowNum'
   FROM 
       dbo.ItemHolder ih
   INNER JOIN 
       dbo.ItemHolderData d ON ih.ItemHolderID = d.ItemHolderID
   WHERE
       ComponentId IN (.....) 
       AND ConsoleTimeStamp <= (threshold)
)
SELECT 
   ItemHolderID, Name, Data
FROM 
   PartitionedComponents
WHERE
   RowNum = 1

在这里,我只为每个“分区”(即每个ItemHolderId)选择最后两个条目 - 按“数据”列以降序方式排序。

这是否接近你正在寻找的东西?

于 2012-06-30T06:54:50.907 回答
2

您可以使用row_number()用户对数据进行分区,然后以 '1' 作为[rank]. 通过这种方式,您可以控制数据的分区和排序,以控制哪些记录被赋予“1”的值,从而返回......

/* Setup tables for query */
declare @tbl1 table (ItemHolderId int, Name varchar(32))
declare @tbl2 table (ItemId int, Data varchar(32), ItemHolderId int)

insert into @tbl1 values (1, 'Holder A'), (2, 'Holder B')

insert into @tbl2 values (1, 'Item A', 1), (2, 'Item B', 1), (3, 'Item C', 1), (4, 'Item D', 1)
insert into @tbl2 values (5, 'Item E', 2), (6, 'Item F', 2), (7, 'Item G', 2)

/* Select data */
select t2.*, row_number() over (partition by t1.ItemHolderId order by t2.ItemHolderId) as [rank]
into #temp
from @tbl1 t1 inner join @tbl2 t2 on t1.ItemHolderId = t2.ItemHolderId

select ItemId, Data, ItemHolderId from #temp where [rank] = 1

drop table #temp
于 2012-06-30T07:08:53.543 回答
0

我认为您也可以对 itemholderid 列使用 group by 功能,我猜它会有所帮助。

select 
   rownum itemId, 
   tmp.name , 
   tmp.itemholderid  
from 
   (select 
       min(t.name) name, 
       t.itemholderid  
    from 
       table_name t 
    group by t.itemholderid
   )tmp;
于 2012-06-30T07:02:57.177 回答