【问题标题】:Being unable to run query in Microsoft SQL Server无法在 Microsoft SQL Server 中运行查询
【发布时间】:2014-09-01 23:26:11
【问题描述】:

我在运行/配置 Microsoft SQL Server 查询时遇到问题,查询如下:

SELECT
    ps.WeekIncluded AS PaidWeeks,
    PayD.PayDate AS PayDates,
    ps.PayYear AS PYear, 
    months.PMonth,
    (SELECT sum(DayPay) FROM Shifts GROUP BY WeekNumber)
FROM dbo.PayStructure ps
JOIN dbo.Months Months 
ON ps.MonthID = months.ID
JOIN dbo.PayDates PayD ON ps.MonthID = PayD.MonthID
Group BY ps.MonthID

这是尝试做的,是使用三个表创建一个视图(不包含在 sn-p 中),包括选择 DayPay in Shifts 和 GroupBy 的总和,以便稍后加入并通过 weeknumber 加入到指定月份。不幸的是,我得到了:

选择列表中的“dbo.PayStructure.WeekIncluded”列无效 因为它既不包含在聚合函数中,也不包含在 GROUP BY 子句。

& 使用:

SELECT
    ps.WeekIncluded AS PaidWeeks,
    PayD.PayDate AS PayDates,
    ps.PayYear AS PYear, 
    months.PMonth,
    (SELECT sum(DayPay) FROM Shifts)
FROM dbo.PayStructure ps
JOIN dbo.Months Months 
ON ps.MonthID = months.ID
JOIN dbo.PayDates PayD ON ps.MonthID = PayD.MonthID

返回:

每个选择等于:60.36 我想要得到的是:

一月 - 空

2 月 - 空

三月 - 空

4 月 - 空

五月 - 空

六月 - 空

7 月 - 空

8 月 - 空

9 月 - 60.36

10 月 - 空

12 月 - 空

由于没有这些周数/月的数据输入,因此 11/12 个月为空


按要求。 Dbo.Shifts

Dbo.PayStructure

Dbo.Months


尝试过:

    SELECT
     ps.WeekIncluded AS PaidWeeks, 
     PayD.PayDate AS PayDates,
     ps.PayYear AS PYear,
       SUM(Sh.DayPay) 
FROM   dbo.PayStructure ps
       LEFT JOIN dbo.Months Months 
         ON ps.MonthID = months.ID
       LEFT JOIN dbo.PayDates PayD
         ON ps.MonthID = PayD.MonthID
        LEFT JOIN dbo.Shifts Sh
         ON Sh.WeekNumber = ps.WeekIncluded
GROUP  BY Sh.WeekNumber

【问题讨论】:

  • 你能发布一些包含一些行的示例输入表吗?
  • @BoratSagdiyev 请查看引用表格的屏幕截图更新

标签: sql sql-server


【解决方案1】:
SELECT
ps.WeekIncluded AS PaidWeeks,
PayD.PayDate AS PayDates,
ps.PayYear AS PYear, 
months.PMonth,
SumPay
FROM dbo.PayStructure ps
JOIN dbo.Months Months 
ON ps.MonthID = months.ID
JOIN dbo.PayDates PayD ON ps.MonthID = PayD.MonthID
LEFT JOIN 
(SELECT S. WeekNumber,
            PSI.MonthId,
            PSI.PayYear,
            sum(DayPay) AS SumPay
FROM Shifts S
JOIN dbo.PayStrycture PSI
ON S.WeekNumber = PSI.WeekIncluded
AND YEAR(S.ShiftDate) = PSI.PayYear
JOIN dbo.Months M
ON PSI.MonthId = M.ID
GROUP BY S. WeekNumber,
            PSI.MonthId,
            PSI.PayYear
) T
ON PS.MonthId = T.MonthId
AND PS.PayYear = T.PayYear
AND PS.WeekIncluded = T.WeekNumber

【讨论】:

  • 这就像一个绝对的魅力。不过,如果不是太麻烦的话。您能详细介绍一下对原始查询所做的更改吗?
  • @darylgill 您必须认为有两个单独的表。第一个是所有可能的几周、几个月和几年的时间。尝试我的查询从 LEFT JOIN 和之后删除任何内容(也从列列表中删除 SumDay)并查看这些结果。
  • 然后运行 ​​LEFT JOIN 之后定义的选择中的任何内容。这是您的实际计算数据。下一步是将可能的时间表与计算出的数据结合起来。我希望我在解释方面做得很好......
  • 我完全按照这个查询的情况。虽然我遇到了另一个问题,我正试图弄清楚自己,但有点超出了这个区域。通过连接 PaidWeeks 按 Pmonth 分组
【解决方案2】:

错误信息相当清楚; SQL Server 无法从您的查询中知道WeekIncluded 的哪个可能值应该包含您查询的结果集。你自己想一想——你的输出中每个月会有一行,而 WeekIncluded 值会有一个“槽”。应该显示哪一个?

尝试像这样运行查询:

SELECT
    MIN(ps.WeekIncluded) AS FromWeek,
    MAX(ps.WeekIncluded) AS ToWeek,
    . . . 

你应该对正在发生的事情有一个更好的了解。

其他几个引擎包含一个名为 group_concat 的额外聚合函数来处理此类查询,但 SQL Server 很难在这样的聚合中汇总以逗号分隔的值列表。

【讨论】:

  • 最小/最大值返回 1 - 52,这是预期和已知的,因为一年中有 52 周。将研究字符串的连接,因为这似乎可能是问题的原因
  • 嗯,已经有问题了。根据您发布的数据,MonthID 1 的 MIN/MAX 值应该是 37 和 40。我猜实际上,MonthID 4 显示值 1 和 52,因为 WeekIncluded 值的方式环绕。要将它们放入“正确”的插槽中,您需要比较差异的绝对值,如果大于 5,则反转这些值。
【解决方案3】:

任何非聚合的 SELECT 列(例如 SUM() 或 COUNT())都必须包含在 GroupBy 中,否则查询将不会执行。

所以:

SELECT
ps.WeekIncluded AS PaidWeeks,
PayD.PayDate AS PayDates,
ps.PayYear AS PYear, 
months.PMonth,
(SELECT sum(DayPay) FROM Shifts GROUP BY WeekNumber)
FROM dbo.PayStructure ps
JOIN dbo.Months Months 
ON ps.MonthID = months.ID
JOIN dbo.PayDates PayD ON ps.MonthID = PayD.MonthID
Group BY ps.MonthID,ps.WeekIncluded,PayD.PayDate,months.PMonth

【讨论】:

  • 我认为用户显然希望每个月输出一条记录。解决方案不是 GROUP BY WeekIncluded,而是以某种有意义的方式聚合它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多