如何根据 A 列中的数据将 B 列的 SQL 搜索结果汇总为总和?

Posted

技术标签:

【中文标题】如何根据 A 列中的数据将 B 列的 SQL 搜索结果汇总为总和?【英文标题】:How to summarize SQL search result of column B as sum based on data in column A? 【发布时间】:2018-05-30 09:41:02 【问题描述】:

我创建了一个 SQL 公式来搜索特定机器的信号状态所花费的时间:

SELECT 'Core' as Core, Z.EventName, ISNULL(DIFF,0) AS DIFF 
FROM (select distinct MacID, EventName from dbo.tblMachine a  
join (SELECT DISTINCT EVENTNAME FROM dbo.tblEvtDur) 
b on b.EventName <> '' and MacID in ('A06','A07', 'A08', 'A09', 'B01','B05','B09', 'B10', 'B11', 'C04', 'C08', 'C09') ) 
z LEFT JOIN (SELECT A.MacID, A.EventName, SUM(DATEDIFF(SECOND, A.STARTdt, A.eNDdt)) 
as diff,round(SUM(DATEDIFF(SECOND, A.STARTdt, A.eNDdt)) / cast(aVG(Tdiff) 
as decimal(30,8)),4) * 100 AS PER FROM dbo.tblEvtDur  A 
LEFT JOIN ( SELECT macid, SUM(DATEDIFF(SECOND, STARTdt, eNDdt)) as Tdiff 
FROM  dbo.tblEvtDur  WHERE DayID between '20180401' and '20180430'  
GROUP BY MacID ) B ON  A.MacID = B.MacID 
WHERE DayID between '20180401' and '20180430'  
AND A.MacID in
 ('A06','A07', 'A08', 'A09', 'B01','B05','B09', 'B10', 'B11', 'C04', 'C08', 'C09') 
group by A.MacID, A.EventName) a 
ON A.EVENTNAME = Z.EVENTNAME  and Z.MacID  = a.MacID order by Z.MacID, Z.EventName

我得到的结果如下所示:

现在我想让 SQL 显示这些特定机器的 EventName BLK、MDL、MTL、OFF、RPR 和 RUN 的总和。这可能吗?

编辑:

如果我尝试使用 group by 子句添加 sum,它不适用于当前 SQL。

所以我不得不把它重构成这样:

select 'Core' as Core, EventName, sum(DATEDIFF(second, startdt, EndDT)) as DIFF 
from dbo.tblEvtDur

where MacID in ('A06','A07','A08','A09','B01','B05','B09','B10','B11','C04','C08','C09')

and DayID between '20180531' and '20180531'

group by eventname

但根据日期,某些信号不会出现,因此未在结果表中列出。

我应该添加什么来告诉 SQL 将 EventName BLK 显示为 0?

编辑 2:

到目前为止,尝试了 Dan 使用右连接的建议:

select 'Core' as [Core], a.EventName, isnull((sum(DATEDIFF(second, startdt, EndDT))),0) as DIFF 
from dbo.tblEvtDur a
right join (select distinct eventname from dbo.tblEvtDur where EventName in     
('BLK', 'MDL', 'MTL', 'OFF', 'RPR', 'RUN')) b 
on a.EventName = b.EventName
where MacID in ('A06','A07', 'A08', 'A09', 'B01','B05',
'B09', 'B10', 'B11', 'C04', 'C08', 'C09')
and DayID between '20180531' and '20180531'
group by a.eventname

同样,结果相同,但花费的时间明显更长。

【问题讨论】:

您可以将唯一事件名称的列表右加入到您的查询中:RIGHT JOIN (SELECT DISTINCT EventName from dbo.tblMachine) AS names ON yourPreviousQuery.EventName = names.EventName,然后使用ISNULLNULL 值转换为0 我还应该提到 dbo.tblMachine 不包含 EventName 列,它仅在 dbo.tblEvtDur 中独占。一定是误输入了…… 在右连接查询中使用 b.EventName 代替 a.EventName。您正在使用 a.EventName 这就是它给您相同结果的原因。 您的意思是将group by a.eventname 替换为group by b.eventname 吗?因为我试过了,我收到了另一条消息Column 'dbo.tblEvtDur.EventName' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.我在这里做错了什么? 【参考方案1】:

使用聚合函数(sum、count、avg...)和 group by。

 select count(*) from (output of your query) group by EventName;

【讨论】:

【参考方案2】:

由于格式的原因,您的代码有点难以阅读,但正如@Piyush Ghediya 回答的那样,您可以将 sum 与 group by 子句一起使用。

SELECT 'Core' as Core, Z.EventName, Sum(ISNULL(DIFF,0)) AS DIFF 
FROM (select distinct MacID, EventName from dbo.tblMachine a  
join (SELECT DISTINCT EVENTNAME FROM dbo.tblEvtDur) 
b on b.EventName <> '' and MacID in ('A06','A07', 'A08', 'A09', 'B01','B05','B09', 'B10', 'B11', 'C04', 'C08', 'C09') ) 
z LEFT JOIN (SELECT A.MacID, A.EventName, SUM(DATEDIFF(SECOND, A.STARTdt, A.eNDdt)) 
as diff,round(SUM(DATEDIFF(SECOND, A.STARTdt, A.eNDdt)) / cast(aVG(Tdiff) 
as decimal(30,8)),4) * 100 AS PER FROM dbo.tblEvtDur  A 
LEFT JOIN ( SELECT macid, SUM(DATEDIFF(SECOND, STARTdt, eNDdt)) as Tdiff 
FROM  dbo.tblEvtDur  WHERE DayID between '20180401' and '20180430'  
GROUP BY MacID ) B ON  A.MacID = B.MacID 
WHERE DayID between '20180401' and '20180430'  
AND A.MacID in
 ('A06','A07', 'A08', 'A09', 'B01','B05','B09', 'B10', 'B11', 'C04', 'C08', 'C09') 
group by A.MacID, A.EventName) a 
ON A.EVENTNAME = Z.EVENTNAME  and Z.MacID  = a.MacID order by Z.MacID, Z.EventName
Group by Core, Eventname

【讨论】:

最后一行出现错误Incorrect syntax near the keyword 'Group'【参考方案3】:

您需要这样的东西,因为您需要在单个查询中包含 sum 和 condition 的所有必需值。

DECLARE @tbl TABLE(name VARCHAR(50), quantity INT, saledate DATE)
INSERT INTO @tbl(name, quantity, saledate)
VALUES('A', 20, '2018-05-31'), ('B', 50, '2018-05-25'), ('c', 40, '2018-05-20'), ('a', 40, '2018-05-10'), ('d', 20, '2018-05-15'), ('c', 20, '2018-05-20')
SELECT a.name, SUM(CASE WHEN a.saledate > '2018-05-15'
  THEN a.quantity ELSE 0 END)
FROM @tbl a
WHERE(a.saledate > '2018-05-15'
  OR a.name in ('a', 'b', 'c', 'd')) GROUP BY a.name

【讨论】:

【参考方案4】:

终于找到了解决问题的方法,我所要做的就是从选择函数中删除 MacID 并声明 EventName:

SELECT 'Core' as Core, Z.EventName, ISNULL(DIFF,0) AS DIFF FROM 
(select distinct EventName from dbo.tblMachine a 

join 
(SELECT DISTINCT EVENTNAME FROM dbo.tblEvtDur) b 
on b.EventName <> '' and eventname in ('BLK', 'MDL', 'MTL', 'OFF', 'RPR', 'RUN') 
and MacID in ('A06','A07', 'A08', 'A09', 'B01','B05','B09', 'B10', 'B11', 'C04', 'C08', 'C09')) Z 

LEFT JOIN (SELECT A.EventName, SUM(DATEDIFF(SECOND, A.STARTdt, A.eNDdt)) as diff, 
round(SUM(DATEDIFF(SECOND, A.STARTdt, A.eNDdt)) / cast(aVG(Tdiff) as decimal(30,8)),4) * 100 AS PER 
FROM dbo.tblEvtDur  A 

LEFT JOIN ( SELECT EVENTNAME, SUM(DATEDIFF(SECOND, STARTdt, eNDdt)) as Tdiff 
FROM dbo.tblEvtDur  WHERE DayID between '20180401' and '20180430' GROUP BY EVENTNAME ) B 
ON  A.EVENTNAME = B.EVENTNAME 

WHERE DayID between '20180401' and '20180430' 
AND A.MacID in ('A06','A07', 'A08', 'A09', 'B01','B05','B09', 'B10', 'B11', 'C04', 'C08', 'C09') 
and A.eventname in ('BLK', 'MDL', 'MTL', 'OFF', 'RPR', 'RUN') 
group by A.EventName) a ON A.EVENTNAME = Z.EVENTNAME and Z.EVENTNAME  = a.EVENTNAME order by  Z.EventName

【讨论】:

以上是关于如何根据 A 列中的数据将 B 列的 SQL 搜索结果汇总为总和?的主要内容,如果未能解决你的问题,请参考以下文章

在 SQL Oracle 的 B 列中搜索 A 列的每个值

根据另一列的值过滤数据框列[重复]

在线等。。。。SQL中如何将一个表中的某一列的数据替换到另一个表中的某一列里。

根据表中其他列的值从同一表中的 2 列中选择信息

pandas中的SQL查询:根据其他列的组合在列中连接多行

如何在 Ruby 中创建 CSV 文件的某些列的副本,其中一列中有不同的数据?