【问题标题】:SQL Query to filter record for particular record countSQL查询过滤特定记录计数的记录
【发布时间】:2012-09-25 06:28:49
【问题描述】:

我有一个表,其中包含 Identity、RecordId、Type、Reading 和 IsDeleted 列。 Identity 是自动递增的主键,RecordId 是可以有重复值的整数,Type 是可以是“一”或“平均”的读数类型,读数是包含任何整数值的整数,IsDeleted 是位可以是 0 或 1,即假或真。 现在,我希望查询包含表的所有记录,如果每个 RecordId 的 COUNT(Id) 大于 2,则显示该 RecordId 的所有记录。

如果该特定 RecordId 的 COUNT(Id) == 2 并且两者的读数值,即“一个”或“平均”类型的记录相同,则仅显示平均记录。

如果 COUNT(Id) ==1 则仅显示该记录。

例如:

Id          RecordId          Type          Reading       IsDeleted 
1           1                 one             4              0
2           1                 one             5              0
3           1                 one             6              0
4           1                 average         5              0
5           2                 one             1              0
6           2                 one             3              0
7           2                 average         2              0
8           3                 one             2              0
9           3                 average         2              0
10          4                 one             5              0
11          4                 average         6              0
12          5                 one             7              0

Ans 结果可以是

Id          RecordId          Type          Reading       IsDeleted 
1           1                 one             4              0
2           1                 one             5              0
3           1                 one             6              0
4           1                 average         5              0
5           2                 one             1              0
6           2                 one             3              0
7           2                 average         2              0
9           3                 average         2              0
10          4                 one             5              0
11          4                 average         6              0
12          5                 one             7              0

简而言之,我想跳过具有相同值的平均读数的“一”型读数,并且“一”型读数的计数不超过一。

【问题讨论】:

  • 人们对此进行了标记,但不准备评论原因(非常烦人)-问题不太清楚,但还有很多更糟糕的问题-您是否尝试过编写查询?你能告诉我们你的尝试吗?
  • 获得 8 票赞成的还有很多 :(

标签: sql sql-server sql-server-2008 tsql sql-server-2008-r2


【解决方案1】:

看看这个程序

DECLARE @t TABLE(ID INT IDENTITY,RecordId INT,[Type] VARCHAR(10),Reading INT,IsDeleted BIT)
INSERT INTO @t VALUES
(1,'one',4,0),(1,'one',5,0),(1,'one',6,0),(1,'average',5,0),(2,'one',1,0),(2,'one',3,0),
(2,'average',2,0),(3,'one',2,0),(3,'average',2,0),(4,'one',5,0),(4,'average',6,0),(5,'one',7,0),
(6,'average',6,0),(6,'average',6,0),(7,'one',6,0),(7,'one',6,0)
--SELECT * FROM @t

;WITH GetAllRecordsCount AS                              
(   
    SELECT *,Cnt = COUNT(RecordId) OVER(PARTITION BY RecordId ORDER BY RecordId)
    FROM @t
)
-- Condition 1 : When COUNT(RecordId) for each RecordId is greater than 2 
 --               then display all the records of that RecordId. 
, GetRecordsWithCountMoreThan2 AS
(
    SELECT * FROM GetAllRecordsCount WHERE Cnt > 2
)
-- Get all records where count = 2
, GetRecordsWithCountEquals2 AS
(
    SELECT * FROM GetAllRecordsCount WHERE Cnt = 2
)
-- Condition 3 : When COUNT(RecordId) == 1 then display only that record.
, GetRecordsWithCountEquals1 AS
(
    SELECT * FROM GetAllRecordsCount WHERE Cnt = 1
)

-- Condition 1: When COUNT(RecordId) > 2
SELECT * FROM GetRecordsWithCountMoreThan2  UNION ALL

-- Condition 2 : When  COUNT(RecordId) == 2 for that specific RecordId and Reading value of 
--               both i.e. 'one' or 'average' type of the records are same then display only 
--               average record. 
SELECT t1.* FROM GetRecordsWithCountEquals2 t1
JOIN (Select RecordId From GetRecordsWithCountEquals2 Where [Type] = ('one') )X
ON t1.RecordId = X.RecordId
AND t1.Type = 'average'     UNION ALL   

-- Condition 2: When COUNT(RecordId) = 1
SELECT * FROM GetRecordsWithCountEquals1    

结果

ID  RecordId    Type    Reading IsDeleted   Cnt
1   1            one    4             0     4
2   1            one    5             0     4
3   1            one    6             0     4
4   1            average5             0     4
5   2            one    1             0     3
6   2            one    3             0     3
7   2            average2             0     3
9   3            average2             0     2
11  4            average6             0     2
12  5            one    7             0     1

【讨论】:

    【解决方案2】:
    ;with a as
    (
    select Id,RecordId,Type,Reading,IsDeleted, count(*) over (partition by RecordId, Reading) cnt, 
    row_number() over (partition by RecordId, Reading order by Type, RecordId) rn
    from table
    )
    select Id,RecordId,Type,Reading,IsDeleted
    from a where cnt <> 2 or rn = 1
    

    【讨论】:

    • @DevendraGohil - 如果这完成了工作,那么为什么原始帖子中的记录 id=2 但此答案没有返回?!你原来的帖子错了吗?
    【解决方案3】:

    假设您的表名为the_table,让我们这样做:

    select main.*
    from the_table as main
    inner join (
      select recordId, count(Id) as num, count(distinct Reading) as reading_num
      from the_table
      group by recordId
    ) as counter on counter.recordId=main.recordId
    where num=1 or num>2 or reading_num=2 or main.type='average';
    

    未经测试,但应该是它的一些变体。

    编辑 TEST HERE ON FIDDLE

    简短的总结是,我们想用 o=itself 的聚合版本加入表,然后根据您提到的计数标准过滤它(num=1,然后显示它;num=2,只显示平均记录如果读数相同,否则显示两者;num>2,显示所有记录。

    【讨论】:

    • 谢谢。但是这里没有必要必须存在所有记录的平均值。我希望如果“one”类型的记录只是单个记录,并且其记录 ID 存在于“平均”类型的记录中,则丢弃“one”类型的记录。
    • 请记住,我添加main.type='average' 只会触发num=2 的记录,因为num=1 or num&gt;2 将涵盖其他基础。 where 子句可以重写为(num=1 or num&gt;2 or (num=2 and main.type='average')),但这样做是多余的,因此没有必要,所以我把它去掉了。
    • 似乎有效:SQL FIDDLE ...实际上 ID 10 也已被排除在外
    • 根据他的标准,绝对应该排除它。 ID 10 和 11 的 RecordId=4,因此应该显示 11,因为它的类型为“平均”。
    • @chops ...我可以在你的帖子中添加小提琴吗?
    猜你喜欢
    • 1970-01-01
    • 2018-08-17
    • 1970-01-01
    • 1970-01-01
    • 2023-02-26
    • 1970-01-01
    • 2011-03-18
    • 2016-04-05
    • 1970-01-01
    相关资源
    最近更新 更多