Sql server SQL Server:按分组列求和并按另一列排序
我想结合所有类似的位置(名称)和总和的数量(卷)为该位置,并在这里按月日排序的结果。我试图选择一个子集并像这里一样内部连接这些值,但一直得到group by not in AGGRATE子句错误,感谢您的提示!!Sql server SQL Server:按分组列求和并按另一列排序,sql-server,Sql Server,我想结合所有类似的位置(名称)和总和的数量(卷)为该位置,并在这里按月日排序的结果。我试图选择一个子集并像这里一样内部连接这些值,但一直得到group by not in AGGRATE子句错误,感谢您的提示!! 结果应按月日排序,同一天具有相同位置的行应在一行而不是多行上求和。 以下是我的Select语句,没有分组或求和: SELECT day_of_month AS 'Day of Month', run_ticket AS 'Ticket number',
结果应按月日排序,同一天具有相同位置的行应在一行而不是多行上求和。 以下是我的Select语句,没有分组或求和:
SELECT
day_of_month AS 'Day of Month',
run_ticket AS 'Ticket number',
ticketdate AS 'Ticket Date',
id AS 'location id',
name AS 'location',
vol AS 'Volume',
ord_rev AS 'OrderHeader'
FROM
#RECORDS R
ORDER BY
day_of_month
目前的结果:
按月日排序,当天的相同位置不会汇总在一行中。
预期结果:
按月日排序,当天的相同位置汇总在一行中。
我还计算了每天和运行日期的总容量,但在SSRS中这样做。
我正在尝试这样的解决方案
SELECT day_of_month AS 'Day of Month'
,run_ticket AS 'Ticket Number'
,ticketdate AS 'Ticket Date'
,r2.cmp_id AS 'Location ID'
,cmp_name AS 'location'
,SUM(vol) AS 'Volume'
,ord_rev AS 'OrderHeader'
FROM #RECORDS as r2
JOIN
(SELECT cmp_id, SUM(vol) AS 'Volume'
FROM #RECORDS
GROUP BY cmp_name
) AS s ON s.cmp_id = r2.cmp_id
GROUP BY r2.cmp_name
ORDER BY day_of_month
当我运行proc时,我得到
Msg 8120,16级,状态1,程序DailyLoadReportMTD,第78行[批次起始行109]
列“#RECORDS.cmp_id”在选择列表中无效,因为它未包含在聚合函数或GROUP BY子句中
好吧,埃里克的回答让我接近了!如果我按r.cmp\u name,r.ord\u revtype2,r.day\u of\u month进行分组,只需要消除重复,我必须添加r.ofr\u BSWheight,这将强制执行重复行。。。或抛出无效的选择错误(不包含该错误)
Aggrergate函数仅在SELECT子句中使用。我知道您只想显示卷的总和,因此需要添加(总和)卷。问题描述引出了一个问题“您想按哪个月的哪一天下单” 由于您在
name
上分组以获得vol
的总和,因此可以公平地假设每个name
将有多个R
,每个R
的值可能不同
可能不会导致“非聚合”错误的有效排序表达式有按最小值排序(每月的第几天)
或按最大值排序(每月的第几天)
。。。。你甚至可以使用AVG或SUM,但这没有多大意义
另外,
“
是字符串分隔符,而不是标识符分隔符。在MSSQL中,您使用ansi标准“
或MS特有的[
和]
,因为您需要所有这些列,所以窗口功能可能会更好。这样行吗
SELECT day_of_month AS 'Day of Month'
, run_ticket AS 'Ticket Number'
, ticketdate AS 'Ticket Date'
, cmp_id AS 'Location ID'
, cmp_name AS 'location'
, SUM(vol) OVER(PARTITION BY day_of_month, cmp_name) AS 'Volume'
, ord_rev AS 'OrderHeader'
FROM #RECORDS
由于删除了一些列,因此简单的分组方式应该可以工作
SELECT day_of_month AS 'Day of Month'
, cmp_id AS 'Location ID'
, cmp_name AS 'location'
, SUM(vol) AS 'Volume'
, ord_rev AS 'OrderHeader'
FROM #RECORDS
GROUP BY day_of_month, cmp_id, cmp_name, ord_rev
我用另一张临时表和CTE算出了
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
IF OBJECT_ID('tempdb..#RECORDS') IS NOT NULL
BEGIN
DROP TABLE #RECORDS
END
IF OBJECT_ID('tempdb..#RECORDS2') IS NOT NULL
BEGIN
DROP TABLE #RECORDS2
END
-- Insert statements for procedure here
CREATE TABLE #RECORDS
(
day_of_month int
--,run_ticket varchar(255)
,inv_seal_ondate datetime
,cmp_id varchar(255)
,cmp_name varchar(255)
,ofr_BSWHeight decimal
,ord_revtype2 varchar(255)
)
CREATE TABLE #RECORDS2
(
day_of_month int
--,run_ticket varchar(255)
,inv_seal_ondate datetime
,cmp_id varchar(255)
,cmp_name varchar(255)
,ofr_BSWHeight decimal
,ord_revtype2 varchar(255)
)
-- Initial population of Records temp table ------------------
INSERT INTO #RECORDS
( day_of_month
--,run_ticket
,inv_seal_ondate
,cmp_id
,cmp_name
,ofr_BSWHeight
,ord_revtype2
)
SELECT
(SELECT DAY(inv_seal_ondate)) --day_of_month extracted from inv_seal_ondate
--,o.run_ticket
,o.inv_seal_ondate
,c.cmp_id
,c.cmp_name
,o.ofr_BSWHeight
,oh.ord_revtype2
FROM OFR o
INNER JOIN company c on o.cmp_id = c.cmp_id
INNER JOIN orderhead oh on oh.ord_hdrnumber = o.ord_hdrnumber
WHERE o.inv_seal_ondate between @StartDate and @EndDate
AND c.cmp_altid in (@Company_AltId)
AND oh.ord_revtype2 in (@RevType2)
INSERT INTO #RECORDS2
( day_of_month
--,run_ticket
,inv_seal_ondate
,cmp_id
,cmp_name
,ofr_BSWHeight
,ord_revtype2
)
SELECT
day_of_month AS 'Day of Month'
--,run_ticket AS 'Run Ticket'
,inv_seal_ondate AS 'Ticket Date'
,cmp_id AS 'Lease ID'
,cmp_name AS 'Lease Name'
,SUM(ofr_BSWHeight) OVER(PARTITION BY day_of_month , cmp_name) AS 'NSV'
,ord_revtype2 AS 'OrderHeaderRevType2'
FROM #RECORDS r
ORDER BY day_of_month
;WITH cte AS (
Select
day_of_month
,inv_seal_ondate
,cmp_name
,ofr_BSWHeight
,ord_revtype2
,ROW_NUMBER() OVER (
PARTITION BY
day_of_month
,cmp_name
ORDER BY
day_of_month
) row_num
FROM
#RECORDS2
)
DELETE FROM cte
WHERE row_num > 1;
-------------- Return Primary Result Set ----------------------------
SELECT
day_of_month AS 'Day of Month'
--,run_ticket AS 'Run Ticket'
,inv_seal_ondate AS 'Ticket Date'
,cmp_id AS 'Lease ID'
,cmp_name AS 'Lease Name'
,ofr_BSWHeight AS 'NSV'
,ord_revtype2 AS 'OrderHeaderRevType2'
FROM #RECORDS2 r2
ORDER BY day_of_month
END
请向我们展示样本数据和预期结果(表格文本)为了澄清您的问题。我在您发布的代码中没有看到,这将导致您提到的错误。@Eric感谢更新!所有未聚合的列都不在GROUP BY
中。因此会出现错误。在外部查询中,您是按cmp\u name
对记录进行分组。如果您有多个相同的记录,会发生什么e> cmp_name
,但不同的是运行\u ticket
或ord_rev
。在这种情况下会选择哪一个?您是否尝试运行代码?这将不会运行。@DGulyasar SUM(vol)这将是函数的正确使用,但我要寻找的不仅仅是:)结果应该按月日排序,同一天的同一地点应该在一行而不是多行上求和。@RayKoren听起来你应该按地点和月日分组。这并不是那么简单对不起,返回了总数对于整个日期范围的位置。就像每次租赁仍然有多行,只是每行上整个运行的总和,我在分区中添加了day\u of_month
。更接近的是,卷是正确的,只需以某种方式删除重复行!如果有多个run\u ticket
,ticketdate
,ord_rev
,您会选择哪一个?按ord_rev删除运行记录单、记录单日期和子组请参见更新的问题!谢谢!
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
IF OBJECT_ID('tempdb..#RECORDS') IS NOT NULL
BEGIN
DROP TABLE #RECORDS
END
IF OBJECT_ID('tempdb..#RECORDS2') IS NOT NULL
BEGIN
DROP TABLE #RECORDS2
END
-- Insert statements for procedure here
CREATE TABLE #RECORDS
(
day_of_month int
--,run_ticket varchar(255)
,inv_seal_ondate datetime
,cmp_id varchar(255)
,cmp_name varchar(255)
,ofr_BSWHeight decimal
,ord_revtype2 varchar(255)
)
CREATE TABLE #RECORDS2
(
day_of_month int
--,run_ticket varchar(255)
,inv_seal_ondate datetime
,cmp_id varchar(255)
,cmp_name varchar(255)
,ofr_BSWHeight decimal
,ord_revtype2 varchar(255)
)
-- Initial population of Records temp table ------------------
INSERT INTO #RECORDS
( day_of_month
--,run_ticket
,inv_seal_ondate
,cmp_id
,cmp_name
,ofr_BSWHeight
,ord_revtype2
)
SELECT
(SELECT DAY(inv_seal_ondate)) --day_of_month extracted from inv_seal_ondate
--,o.run_ticket
,o.inv_seal_ondate
,c.cmp_id
,c.cmp_name
,o.ofr_BSWHeight
,oh.ord_revtype2
FROM OFR o
INNER JOIN company c on o.cmp_id = c.cmp_id
INNER JOIN orderhead oh on oh.ord_hdrnumber = o.ord_hdrnumber
WHERE o.inv_seal_ondate between @StartDate and @EndDate
AND c.cmp_altid in (@Company_AltId)
AND oh.ord_revtype2 in (@RevType2)
INSERT INTO #RECORDS2
( day_of_month
--,run_ticket
,inv_seal_ondate
,cmp_id
,cmp_name
,ofr_BSWHeight
,ord_revtype2
)
SELECT
day_of_month AS 'Day of Month'
--,run_ticket AS 'Run Ticket'
,inv_seal_ondate AS 'Ticket Date'
,cmp_id AS 'Lease ID'
,cmp_name AS 'Lease Name'
,SUM(ofr_BSWHeight) OVER(PARTITION BY day_of_month , cmp_name) AS 'NSV'
,ord_revtype2 AS 'OrderHeaderRevType2'
FROM #RECORDS r
ORDER BY day_of_month
;WITH cte AS (
Select
day_of_month
,inv_seal_ondate
,cmp_name
,ofr_BSWHeight
,ord_revtype2
,ROW_NUMBER() OVER (
PARTITION BY
day_of_month
,cmp_name
ORDER BY
day_of_month
) row_num
FROM
#RECORDS2
)
DELETE FROM cte
WHERE row_num > 1;
-------------- Return Primary Result Set ----------------------------
SELECT
day_of_month AS 'Day of Month'
--,run_ticket AS 'Run Ticket'
,inv_seal_ondate AS 'Ticket Date'
,cmp_id AS 'Lease ID'
,cmp_name AS 'Lease Name'
,ofr_BSWHeight AS 'NSV'
,ord_revtype2 AS 'OrderHeaderRevType2'
FROM #RECORDS2 r2
ORDER BY day_of_month
END