2

我有一组数据,虽然它连接的字段和表的数量非常复杂,但我相信我可以使用此处所需的字段/表来提炼我的问题,以说明这个特定问题。

我有三个表:ClientData、Sources、Prices

这是我当前查询在选择最小值之前的样子:

select c.RecordID, c.Description, s.Source, p.Price, p.Type, p.Weight
from ClientData c
inner join Sources s ON c.RecordID = s.RecordID
inner join Prices p ON s.SourceID = p.SourceID

这会产生以下结果:

RecordID   Description        Source     Price  Type   Weight
=============================================================
001002003  ABC Common Stock   Vendor 1  104.5   Close  1
001002003  ABC Common Stock   Vendor 1  103     Bid    2
001002003  ABC Common Stock   Vendor 2  106     Close  1
001002003  ABC Common Stock   Vendor 2  100     Unknwn 0
111222333  DEF Preferred Stk  Vendor 3  80      Bid    2
111222333  DEF Preferred Stk  Vendor 3  82      Mid    3
111222333  DEF Preferred Stk  Vendor 2  81      Ask    4

我要做的是显示属于同一记录的价格,该记录具有该记录的最小非零权重(因此权重必须大于 0,但它必须是剩余权重中的最小值)。因此,在上面的示例中,对于记录 001002003,我想显示供应商 1 和供应商 2 的收盘价,因为它们的权重均为 1(该记录的最小权重)。但是对于 111222333,我只想显示供应商 3 的出价,因为它的权重 2 是该记录的最小值,非零。我想要的结果是:

RecordID   Description        Source     Price  Type   Weight
=============================================================
001002003  ABC Common Stock   Vendor 1  104.5   Close  1
001002003  ABC Common Stock   Vendor 2  106     Close  1
111222333  DEF Preferred Stk  Vendor 3  80      Bid    2

关于如何实现这一目标的任何想法?

编辑:这适用于 SQL Server Compact Edition。

4

3 回答 3

2

我能够提出解决方案,所以我想我会分享它:

SELECT x.RecordID, VendorSource, VendorPrice
FROM ClientData x
INNER JOIN Sources s ON x.RecordID = s.RecordID
INNER JOIN Prices p ON s.SourceID = p.SourceID
INNER JOIN (SELECT c.RecordID, MIN(Weight) min_weight
            FROM ClientData c
            INNER JOIN Sources s ON c.RecordID = s.RecordID
            INNER JOIN Prices p ON s.SourceID = p.SourceID
            WHERE Weight != 0 
            GROUP BY c.RecordID) w ON x.RecordID = w.RecordID
WHERE p.Weight = w.min_weight

这允许在派生表中的 RecordID 级别上填充最小权重,因此每个 RecordID 有 1 个权重。

对于所有给出答案的人,谢谢;我感谢提供的帮助和任何指导。

于 2012-06-13T00:31:24.163 回答
0

您可以将 RANK() 与 RecordId 上的分区一起使用,并增加权重来“评价”每一行(在完全排除零权重之后),然后简单地过滤掉排名靠前的行。CTE 仅用于保持第二个查询简单 + 清晰

;WITH MyRecords AS
(
    -- Your source query goes here
    select c.RecordID, c.Description, s.Source, p.Price, p.Type, p.Weight
    from ClientData c
    inner join Sources s ON c.RecordID = s.RecordID
    inner join Prices p ON s.SourceID = p.SourceID
)
SELECT RecordID, [Description], [Source], [Price], [Type], [Weight]
FROM
(
    SELECT RecordID, [Description], [Source], [Price], [Type], [Weight], 
           -- With ranking, the lower the weight the better
           Rnk = RANK() OVER (PARTITION BY RecordId ORDER BY [Weight] ASC)
    FROM MyRecords
    -- But exclude Weight 0 entirely
    WHERE [Weight] > 0
) RankedRecords
-- We just want the top ranked records, with ties
WHERE Rnk = 1

编辑帖子后添加的 CE 约束。请参阅如何在 Sql Server Compact Edition SELECT 语句中复制 Rank 函数?关于如何在 CE 中模拟 RANK()。

于 2012-06-06T04:26:20.377 回答
0

我认为你需要稍微改变你的结构才能真正做到你想要的那样工作。基本上,您拥有价格记录的方式是针对 Source 而不是针对似乎在 ClientData 表中的 Item 设置的。通过从 Sources 表中删除 c.Record 编号列并将其放入 Prices 表中,您应该获得我认为您需要的正确的 One(ClientData) to many (Prices) 和 One(ClientData) to many(Sources) 关系.

select c.RecordID, c.Description, s.Source, p.Price, p.Type, p.Weight
from ClientData c
inner join Prices p ON c.RecordID = p.RecordID
inner join Sources s ON s.SourceID = p.SourceID
   AND p.Weight> 0
LEFT OUTER JOIN #Prices p2 ON c.RecordID = p2.RecordID
   AND p2.PriceID <> p.priceID
   AND p2.Weight > 0
   AND p2.Weight < p.Weight
WHERE p2.SourceID IS NULL

如果您进行了上面指定的更改,则此查询将返回您正在查找的确切数据。

于 2012-06-06T04:15:55.160 回答