我正在努力解决SQL查询,我需要你的帮助。说实话,我开始想知道我想要实现的目标是否可以按照我迄今为止的方式完成,但也许你的集体大脑可以提出比我更好的解决方案并证明我采取了良好的方式在开始时(或者我完全错了,我应该从头开始)。
一行有4个重要字段:ItemID
,Item
,Priority
和Group
。这些字段包含唯一有价值的信息,最后将显示的信息。
由于我使用的是SQL Server 2008,因此无法访问LAG
和LEAD
功能,因此我需要对其进行模拟(或者至少,我做过它因为我觉得这对我有用,但我不再那么肯定了。为了获得此结果,我使用了this article from SQLscope中的代码,该代码为您提供了LAG
和LEAD
等效项,我将其限制为具有相同ItemID
的一组行。这会为我的数据集添加7个新的功能列:Rn
,RnDiv2
,RnPlus1Div2
,PreviousPriority
,NextPriority
,{{1 }和PreviousGroup
。
NextGroup
我的SQL查询中的问题是ItemID | Item | Priority | Group | Rn | RnDiv2 | RnPlus1Div2 | PreviousPriority | NextPriority | PreviousGroup | NextGroup
-------- | ------- | -------- | ------- | ----- | ------ | ----------- | ---------------- | ------------ | ------------- | ---------
16777397 | Item 1 | 5 | Group 1 | 1 | 0 | 1 | NULL | NULL | NULL | NULL
16777403 | Item 2 | 5 | Group 2 | 1 | 0 | 1 | NULL | 5 | NULL | Group 2
16777403 | Item 2 | 10 | Group 2 | 2 | 1 | 1 | 5 | NULL | Group 2 | NULL
16777429 | Item 3 | 1000 | Group 3 | 1 | 0 | 1 | NULL | NULL | NULL | NULL
16777430 | Item 4 | 5 | Group 1 | 1 | 0 | 1 | NULL | NULL | NULL | NULL
16777454 | Item 5 | 5 | Group 4 | 1 | 0 | 1 | NULL | NULL | NULL | NULL
16777455 | Item 6 | 5 | Group 5 | 1 | 0 | 1 | NULL | NULL | NULL | NULL
16777459 | Item 6 | 5 | Group 6 | 1 | 0 | 1 | NULL | NULL | NULL | NULL
16777468 | Item 8 | 5 | Group 7 | 1 | 0 | 1 | NULL | NULL | NULL | NULL
16777479 | Item 9 | 5 | Group 4 | 1 | 0 | 1 | NULL | NULL | NULL | NULL
16777481 | Item 10 | 5 | Group 4 | 1 | 0 | 1 | NULL | NULL | NULL | NULL
16777496 | Item 11 | 5 | Group 6 | 1 | 0 | 1 | NULL | NULL | NULL | NULL
16777514 | Item 12 | 5 | Group 4 | 1 | 0 | 1 | NULL | NULL | NULL | NULL
16777518 | Item 13 | 5 | Group 8 | 1 | 0 | 1 | NULL | 10 | NULL | Group 8
16777518 | Item 13 | 10 | Group 8 | 2 | 1 | 1 | 5 | 100 | Group 8 | Group 1
16777518 | Item 13 | 100 | Group 1 | 3 | 1 | 2 | 10 | NULL | Group 8 | NULL
16777520 | Item 14 | 5 | Group 9 | 1 | 0 | 1 | NULL | NULL | NULL | NULL
子句。我将始终根据其WHERE
列过滤行。但有一些微妙之处。无论Group
和Group
成员的数量是多少,我希望它根据以下条件显示在一个且只有一个 Item
中:
Group
出现在同一Item
次多次,则只返回Group
最低的行。如果priority
在同一个Item
中出现多次,但具有相同的Group
,则只有第一次出现示例: for {{ 1}},只返回Priority
值为 5 的行; Item 2
中出现Priority
,但Item
中的Group
也出现Group
,则不应显示Priority
。{li> 示例: Group 1
被选为过滤器。应显示Item 1
,但Item 13
不应显示,因为Group 8
中Priority
Item 13
Group 8
WHERE
只显示Group
WHERE Group = 'Group 1'
1}})。请注意,这只是一个示例。我的真实数据集有超过3000行,其他一些案例可能是我在样本中没有列出的。
就像我说的那样,WHERE Group = 'Group 1' AND (Group = NextGroup AND Priority < NextPriority)
子句中有一个常量,即Item
过滤。
Item 13
我需要更复杂的东西。 AND NOT (CorrectedPriority >= PreviousPriority)
。这对于WHERE
不超过2组的情况很有效。但是对于(SiteName <> PreviousSiteName AND CorrectedPriority >= PreviousPriority)
,它将返回前两行。如果我在Rn = 1
子句中添加PreviousSiteName
之类的内容,则根本没有结果。NULL
。问题是我永远不会返回NULL
行,因为WHERE
将等于Item
。在Item
上添加检查也不起作用。在尝试这个特定的条款时,我一定很累,因为它是完整的垃圾。我将继续尝试找到好的SELECT *
FROM (SELECT ItemID,
Item,
Priority,
Group_,
MIN(Priority) OVER
( PARTITION BY item
) AS interItem_MinPriority
FROM (SELECT ItemID,
Item,
Priority,
Group_,
ROW_NUMBER() OVER
( PARTITION BY Item
ORDER BY Priority ASC
) AS interGrp_Rank
FROM Test_Table
) AS TMP
WHERE interGrp_Rank = 1 -- Exclude all records with the same item/group, but higher priority.
) AS TMP2
WHERE Priority = interItem_MinPriority; -- Exclude which aren't the lowest priority across groups.
条款,但我觉得我的整个方法都是错误的。当同一个{{1}}的条目超过两个时,我不知道如何解决问题。值得注意的是,此查询用于 SSRS 报告,因此我可以使用自定义代码来解析数据集并过滤行(使用表格可能有助于解决{{1}}的问题s有两个以上的条目)。但如果这里有一个SQL天才,有一个可行的解决方案,那就太好了。
PS:如果有人知道如何修复此表并可以向我解释,为他添加额外的cookie。 :d
这是我目前正在使用的修改后的查询。我会考虑使用@ Yellowbedwetter的最新查询,看起来更强大。
{{1}}
答案 0 :(得分:1)
如果我正确理解了这个问题,那么
SELECT *
FROM (SELECT ItemID,
Item,
Priority,
Group_,
MIN(Priority) OVER
( PARTITION BY item
) AS interItem_MinPriority
FROM (SELECT ItemID,
Item,
Priority,
Group_,
ROW_NUMBER() OVER
( PARTITION BY Item,
Group_
ORDER BY Priority ASC
) AS interGrp_Rank
FROM Test_Table
) AS TMP
WHERE interGrp_Rank = 1 -- Exclude all records with the same item/group, but higher priority.
) AS TMP2
WHERE Priority = interItem_MinPriority; -- Exclude which aren't the lowest priority across groups.
我不知道您的SQL Server版本是否支持MIN()OVER()...,但如果不是,您应该能够轻松地解决这个问题。
编辑:处理暂停。
WITH TEST_TABLE (ItemID, Item, Priority, Group_) AS
(
SELECT '16777397','Item 1','5','Group 1' UNION
SELECT '16777403','Item 2','5','Group 2' UNION
SELECT '16777403','Item 2','10','Group 2' UNION
SELECT '16777429','Item 3','1000','Group 3' UNION
SELECT '16777430','Item 4','5','Group 1' UNION
SELECT '16777454','Item 5','5','Group 4' UNION
SELECT '16777455','Item 6','5','Group 5' UNION
SELECT '16777459','Item 6','5','Group 6' UNION
SELECT '16777468','Item 8','5','Group 7' UNION
SELECT '16777479','Item 9','5','Group 4' UNION
SELECT '16777481','Item 10','5','Group 4' UNION
SELECT '16777496','Item 11','5','Group 6' UNION
SELECT '16777514','Item 12','5','Group 4' UNION
SELECT '16777518','Item 13','5','Group 8' UNION
SELECT '16777518','Item 13','10','Group 8' UNION
SELECT '16777518','Item 13','100','Group 1' UNION
SELECT '16777520','Item 14','5','Group 9'
)
SELECT ItemID,
Item,
Priority,
Group_
FROM (SELECT ItemID,
Item,
Priority,
Group_,
ROW_NUMBER() OVER
( PARTITION BY item
ORDER BY Group_ ASC -- or however you want to break the tie
) AS grp_minPriority_TieBreak
FROM (SELECT ItemID,
Item,
Priority,
Group_,
MIN(Priority) OVER
( PARTITION BY item
) AS interItem_MinPriority
FROM (SELECT ItemID,
Item,
Priority,
Group_,
ROW_NUMBER() OVER
( PARTITION BY Item,
Group_
ORDER BY Priority ASC
) AS interGrp_Rank
FROM TEST_TABLE
) AS TMP
WHERE interGrp_Rank = 1 -- Exclude all records with the same item/group, but higher priority.
) AS TMP2
WHERE Priority = interItem_MinPriority -- Exclude which aren't the lowest priority across groups.
) AS TMP2
WHERE grp_minPriority_TieBreak = 1;
答案 1 :(得分:1)
如果我理解你的问题
关于这些标准
如果项目多次出现在同一组中,则只有 应返回优先级最低的行。示例:for Item 2,只返回优先级值为5的行;
如果项目出现在群组中,但也出现在另一个群组中 优先级最低的组,不应显示。例: 选择组1作为过滤器。应显示第1项但是项目 13不应该因为它在第8组中也存在较低的 优先级(第13项仅出现在第8组中)。
我认为我们可以通过使用每个项目的最低优先级而不考虑项目组来获得正确的结果,因为在上述两种情况下,我们采用了项目的最低优先级。
因此以下查询可能会有所帮助。(我使用您的示例数据对其进行了测试)
with minPriority as
(
select ItemID, Item, Priority , Group_,ROW_NUMBER() over(partition by ItemId order by priority )rn from Test_table
)
select * from minPriority where rn=1
答案 2 :(得分:0)
Haven没有尝试过,但是......选择max(优先级)作为mp .....来自......其中group =&#39; group1&#39;和mp不在(选择最大(优先)....来自...其中组&lt;&gt;&#39; group1&#39;
打字道歉,在我的手机上没有眼镜:)