【问题标题】:only single or multiple occurrences records using inner join仅使用内部联接的单个或多个出现记录
【发布时间】:2015-11-19 22:08:02
【问题描述】:

我有以下查询。

select 
dsccnf.Id cnfRptClmId,dsccnf.tblRptcatId cnfRptcatId,dsccnf.Category cnfCategory,
dsccnf.ClmNumber cnfNumber,dsccnf.State cnfState
from tblClmPeriod dcp 
inner join tblRptClm dsccnf on dsccnf.tblClmPeriodId = dcp.Id and dsccnf.State=3 --and dsccnf.tblClmPeriodId = 10288

|cnfRptClmId|cnfRptcatId|cnfCategory|cnfNumber|cnfState
|21341      |1650       |L2         |A        | 3
|21343      |1652       |L2         |A        | 3
|21345      |1657       |T1         |A        | 3
|21347      |1660       |T2         |B        | 3
|21356      |1670       |T1         |A        | 3

获取上述数据,现在我只想获取所有项目(cnfRptClmId,cnfCategory|cnfNumber|cnfState) a) 一种或单一类型的类别加 ClmNumber 列 (T2|B) 即 (|21347|1660|T2|B| 3) 和类似记录

b)所有记录只出现两次,忽略其余记录,即

|21341|1650|L2|A|3
|21343|1652|L2|A|3
|21345|1657|T1|A|3
|21356|1670|T1|A|3

我可以为这两个结果提供两个单独的查询。预先感谢。

【问题讨论】:

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


【解决方案1】:
SELECT *
FROM
(
    SELECT
        dsccnf.Id cnfRptClmId,
        dsccnf.tblRptcatId cnfRptcatId,
        dsccnf.Category cnfCategory,
        dsccnf.ClmNumber cnfNumber,
        dsccnf.State cnfState,
        COUNT(dsccnf.Category) OVER (PARTITION BY dsccnf.Category) categoryCount
    FROM
        tblClmPeriod dcp
        INNER JOIN tblRptClm dsccnf ON dsccnf.tblClmPeriodId = dcp.Id
                                       AND dsccnf.State = 3
)
WHERE categoryCount = 2

COUNT(dsccnf.Category) OVER (PARTITION BY dsccnf.Category) 将在每一行上为您提供 dsccnf.Category 的计数,因此您只需将其包装在子查询中并仅选择类别计数 = 2 的记录

根据下面的评论..您可以为 dsccnf.Category 和 dsccnf.ClmNumber 添加另一个计数,然后检查该计数是否要按它进行过滤。

SELECT *
FROM
(
    SELECT
        dsccnf.Id cnfRptClmId,
        dsccnf.tblRptcatId cnfRptcatId,
        dsccnf.Category cnfCategory,
        dsccnf.ClmNumber cnfNumber,
        dsccnf.State cnfState,
        COUNT(dsccnf.Category) OVER (PARTITION BY dsccnf.Category) categoryCount,
        COUNT(dsccnf.Category) OVER (PARTITION BY dsccnf.Category, dsccnf.ClmNumber) categoryClmCount
    FROM
        tblClmPeriod dcp
        INNER JOIN tblRptClm dsccnf ON dsccnf.tblClmPeriodId = dcp.Id
                                       AND dsccnf.State = 3
)
WHERE categoryCount = 2 -- where category appears twice
      OR categoryClmCount = 1 -- where category/clm appear only once

【讨论】:

  • 我们如何为 Category 加上 ClmNumber 做到这一点,任何想法
  • PARTITION BY 决定了 COUNT 的计算方式。如果您想要 dsccnf.Category、dsccnf.ClmNumber 组合的计数,请使用COUNT(dsccnf.Category) OVER (PARTITION BY dsccnf.Category, dsccnf.ClmNumber)
【解决方案2】:

试试这个:

select 
    dsccnf.Id          cnfRptClmId,
    dsccnf.tblRptcatId cnfRptcatId,
    dsccnf.Category    cnfCategory,
    dsccnf.ClmNumber   cnfNumber,
    dsccnf.State       cnfState
from tblClmPeriod dcp 
inner join tblRptClm dsccnf on dsccnf.tblClmPeriodId = dcp.Id
                           and dsccnf.State=3
group by
    dsccnf.Id,
    dsccnf.tblRptcatId,
    dsccnf.Category,
    dsccnf.ClmNumber,
    dsccnf.State
having count(*) = 2

【讨论】:

  • 这似乎是最简单的,但我无法实际运行它。我尝试更改列并收到这些错误消息。列 'dsccnf.Id' 在选择列表中无效,因为它既不包含在聚合函数中,也不包含在 GROUP BY 子句中。
  • @afr0:SELECT 和 GROUP BY 子句中的列列表必须相同(除了省略 GROUP BY 中的别名)。
猜你喜欢
  • 2014-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-24
  • 1970-01-01
  • 1970-01-01
  • 2013-06-23
相关资源
最近更新 更多