Sql 努力寻找正确的WHERE子句
我正在处理SQL查询,需要您的帮助。老实说,我开始怀疑我想实现的目标是否能像我目前所做的那样实现,但也许你的集体智慧能想出比我更好的解决方案,并证明我在一开始就采取了好的方式(或者我完全错了,我应该从头开始) 数据集 一行有4个重要字段:Sql 努力寻找正确的WHERE子句,sql,sql-server-2008,ssrs-2008,Sql,Sql Server 2008,Ssrs 2008,我正在处理SQL查询,需要您的帮助。老实说,我开始怀疑我想实现的目标是否能像我目前所做的那样实现,但也许你的集体智慧能想出比我更好的解决方案,并证明我在一开始就采取了好的方式(或者我完全错了,我应该从头开始) 数据集 一行有4个重要字段:ItemID、Item、优先级和组。这些字段包含唯一有价值的信息,即最后将显示的信息 当我使用SQL Server 2008时,我无法访问LAG和LEAD函数,因此我需要模拟它们(或者至少,我这样做是因为我认为它对我有用,但我不再那么确定)。为了得到这个结果,我
ItemID
、Item
、优先级
和组
。这些字段包含唯一有价值的信息,即最后将显示的信息
当我使用SQL Server 2008时,我无法访问LAG
和LEAD
函数,因此我需要模拟它们(或者至少,我这样做是因为我认为它对我有用,但我不再那么确定)。为了得到这个结果,我使用了代码,从中可以得到一个LAG
和LEAD
等价物,我将其限制为一组具有相同ItemID
的行。这将向我的数据集中添加7个新的功能列:Rn
,RnDiv2
,RnPlus1Div2
,PreviousPriority
,NextPriority
,PreviousGroup
和NextGroup
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
问题
SQL查询中的问题是WHERE
子句。我将始终根据行的组
列过滤行。但也有一些微妙之处。无论组
一个项目
的成员是多少,我希望它根据以下标准出现在一个且只有一个组
中:
项目
多次出现在同一组
中,则只应返回优先级最低的行。如果项目
在同一组
中多次出现,但具有相同的优先级
,则只应保留第一次出现的项目。例如:对于项目2
,只应返回优先级
值为5的行李>
如果项目出现在组
中,但也出现在另一个组
优先级最低的中,则不应显示该项目。示例:选择组1
作为过滤器<代码>项目1
应显示,但项目13
不应显示,因为它也以较低的优先级出现在组8
中(项目13
仅出现在组8
中)
请注意,这只是一个示例。我的真实数据集有3000多行,其他一些情况可能我没有在示例中列出
失败的尝试
就像我说的,WHERE
子句中有一个常量,那就是组
过滤
- 由于标准#2,我不能简单地这样开始我的子句:
其中Group='group1'
,我需要一些更复杂的东西李>
- 我尝试了以下子句但没有成功:
其中Group='group1'和(Group=nextgroupandpriority
。对于不超过2组的项目
,该方法效果良好。但是对于项目13
,它将返回前两行。如果我在WHERE
子句中添加类似于和NOT(CorrectedPriority>=PreviousPriority)
的内容,则根本不会得到任何结果
- 到目前为止的最后一次尝试:
(SiteName PreviousSiteName和CorrectedPriority>=PreviousPriority)
。问题是我永远不会返回Rn=1
的行,因为PreviousSiteName
将等于NULL
。在NULL
上添加检查也不起作用。我在尝试这一条款时一定累了,因为它完全是垃圾
我会继续努力找到goodWHERE
子句,但我觉得我的整个方法是错误的。当同一项有两个以上的条目时,我不知道如何解决这个问题。值得注意的是,此查询用于SSRS报告,因此我可以使用自定义代码解析数据集并过滤行(使用表可能有助于解决包含两个以上条目的项的问题)。但是如果有一个SQL天才在这里提供一个可行的解决方案,那就太好了
附言:如果有人知道如何修理这张桌子,并能向我解释一下,给他额外的饼干D
编辑:
这是我目前正在使用的修改后的查询。我会考虑使用@ YyButhHeavter的最新查询,它看起来更健壮。p>
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.
没有尝试过,但类似于..选择max(priority)作为mp。。。。。从…起其中组='group1'和mp不在(从…中选择最大优先级)…其中组'group1'
抱歉在我的手机上打字,不要戴眼镜:)如果我正确理解了问题,这应该可以
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;
如果我了解你的问题
关于这些标准
如果项目多次出现在同一组中,则只有
应返回具有最低优先级的行。示例:对于项目
2、只返回优先级值为5的行
如果项目出现在组中,但也出现在另一个组中
优先级最低的组,不应显示该组。例子:
选择组1作为过滤器。应显示项目1,但不显示项目
13不应该,因为它也出现在第8组中,具有较低的
优先权(项目13仅出现在第8组中)
我认为我们可以通过使用每个项目的最小优先级而不考虑项目组b来获得正确的结果
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