【问题标题】:t-sql select all values based on top 5 queryt-sql 根据前 5 个查询选择所有值
【发布时间】:2015-08-19 15:08:52
【问题描述】:

我一直在寻找文档和示例并尝试使这项工作发挥作用,但没有运气,所以我希望有人能指出我正确的方向。

我通过基于月份的查询从名为维护的表中获得了我的前 5 项,基本上给了我本月调用次数最多的前 5 个节点。

例如。前 5 名选择


select top 5  
  maint.node_id
  ,maint.sc_tot
FROM
  server.dbo.maintenance as maint
where
    maint.province_name='provname
and
    maint.system_code='syscode'
and
    maint.city_name='cityname'
and
( 
    year(maint.startdate)=2015
    and 
    month(maint.startdate)=07
)
group by
  maint.node_id
  ,maint.sc_tot

order by
sum(isnull(maint.je_tot,0)+isnull(maint.sc_tot,0)+isnull(maint.tt_tot,0))
desc

输出是

node_id sc_tot 节点1 30 节点2 28 节点3 27 节点4 23 节点5 23

我现在需要做的是为每个节点选择当月调用的总和,而没有时间框架。基本上从同一个维护表中给我每个节点的历史和最终趋势。

例如。快速总结(不确切的细节)

节点开始日期 sc_tot 节点 1 1 月 10 日 节点1 2 月 15 日 节点 1 3 月 36 日 节点 2 1 月 14 日 节点2 2 月 22 日 ETC....

此查询随后将在 sql 报告生成器中用于一些报告和绘图,但只要我有这些值就可以了。

这是否可能只用一个 sql 查询?

【问题讨论】:

  • 你能把那个查询作为一个 cte 吗?然后创建更大的查询并在 node_id 上加入您的 cte
  • CTE = 公用表表达式。语法是with t1 as (Select...), t2 As (Select...) SELECT * from T1 INNER JOIN t2 on T1.ID = T2.FK,本质上它就像在运行时创建的视图,允许您从中进行选择并像视图或表一样加入它。使阅读查询更容易并分离概念。也可以使用内联视图来完成;但通常这些并不那么容易阅读/维护。
  • 我不确定你所说的 cte 是什么意思。你能给我举个例子,说明你用更大的查询引用什么并加入吗?
  • 哦,在关于 cte 的回复中被击败了 18 秒 ;) 是的,我已经尝试过了,但不走运。任何人都可以帮助我采取正确的方法吗?
  • 您能否发布您的 CTE 尝试,结果有什么问题?

标签: sql-server tsql


【解决方案1】:

未经测试...

也许是……

我认为您是在 2015 年 7 月调用量最高的前 5 个节点之后,然后您想要系统中所有前 5 个节点的月/年节点历史记录。

WITH CTE AS (   
  SELECT top 5 a.node_id, a.sc_tot
  FROM server.dbo.maintenance as a
  WHERE a.province_name='provname'
    and a.system_code='syscode'
    and a.city_name='cityname'
    and year(a.startdate)=2015
    and month(a.startdate)=07
  GROUP BY a.node_id ,a.sc_tot
  order by sum(isnull(a.je_tot,0)+isnull(a.sc_tot,0)+isnull(a.tt_tot,0)) desc)


SELECT TopRec.node_ID, sum(maint.sc_tot) as SumOfCalls, 
       year(maint.startdate) as YR, month(maint.startdate) as MO
FROM CTE as TopRec
INNER JOIN server.dbo.maintenance as maint
  on CTE.Node_Id = Maint.Node_ID
GROUP BY TopRec.node_ID, year(maint.startdate), month(maint.startdate)

这和这个(内联视图)本质上是一样的:但是使用了一种更新的技术……你可以看到为什么人们更喜欢它的可读性。

SELECT TopRec.node_ID, sum(maint.sc_tot) as SumOfCalls, 
       year(maint.startdate) as YR, month(maint.startdate) as MO
FROM (    
  SELECT top 5 a.node_id, a.sc_tot
  FROM server.dbo.maintenance as a
  WHERE a.province_name='provname'
    and a.system_code='syscode'
    and a.city_name='cityname'
    and year(a.startdate)=2015
    and month(a.startdate)=07
  GROUP BY a.node_id ,a.sc_tot
  order by sum(isnull(a.je_tot,0)+isnull(a.sc_tot,0)+isnull(a.tt_tot,0)) desc)) 
  as TopRec
  INNER JOIN server.dbo.maintenance as maint
    on CTE.Node_Id = Maint.Node_ID
  GROUP BY TopRec.node_ID, year(maint.startdate), month(maint.startdate)

【讨论】:

  • 谢谢 :D 我知道你现在要去哪里了。我刚刚开始阅读有关 CTE 的信息,因为我以前从未使用过它,但是看到一个与我正在研究的内容直接相关的示例是一个巨大的帮助!我会做一些测试,看看它是如何工作的。
  • 稍微调整一下就完美了!通过手动单独拉取节点来验证数据,并且它正在大放异彩。非常感谢您的帮助,非常感谢!
【解决方案2】:

以下应该有效:

select top 5  
  maint.node_id
  ,convert(char(3), maint.startdate, 0) [mon]
  ,maint.sc_tot
FROM
  server.dbo.maintenance as maint
where
    maint.province_name='provname'
and
    maint.system_code='syscode'
and
    maint.city_name='cityname'
and
    year(maint.startdate)=2015
group by
  maint.node_id
  ,month(maint.startdate)
  ,maint.sc_tot

order by
sum(isnull(maint.je_tot,0)+isnull(maint.sc_tot,0)+isnull(maint.tt_tot,0))
desc

虽然未经测试

【讨论】:

  • 也许我弄错了,但我认为 OP 是根据 2015 年 7 月调用次数最多的 5 个节点的所有历史信息。这不会按月返回前 5 个节点在 2015 年?这可能与 7 月份调用的前 5 个节点不同?
  • 我无法使用此方法,但前面的示例成功了。感谢您发布您的建议 :)
  • @xQbert 也许我通过查看示例数据集误解了它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-07
  • 2014-02-21
  • 1970-01-01
  • 2015-11-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多