SQL Group By中的错误

时间:2017-10-07 00:20:50

标签: sql

我正在做家庭作业,这就是问题:

  • 创建一个名为ShipItemsBrands的视图,该视图返回Shipments,ShipItems和Brands表中的列。

  • 此视图应从Shipments表中返回这些列:ShipmentID,ShipmentOrderDate,TaxAmount和ShipDate。

  • 此视图应从ShipItems表中返回这些列:ShipItemPrice,ShipItemDiscountAmount,FinalPrice(从项目价格中减去的折扣金额),Quantity和ItemTotal(项目的计算总计)。

  • 此视图应从品牌表中返回BrandName列。

这是我的代码:

CREATE VIEW ShipItemsBrand 
AS 
    SELECT 
        sh.ShipmentID, sh.ShipmentOrderDate, sh.TaxAmount, sh.ShipDate,
        si.ShipItemPrice, si.ShipItemDiscountAmount, 
        SUM(si.ShipItemPrice - si.ShipItemDiscountAmount) As FinalPrice, 
        si.Quantity, 
        SUM((si.ShipItemPrice - si.ShipItemDiscountAmount) * si.Quantity) AS ItemTotal,
        b.BrandName
    FROM 
        Brands AS b 
    JOIN 
        ShipItems AS si ON b.BrandID = si.BrandID
    JOIN 
        Shipments AS sh ON si.ShipmentID = sh.ShipmentID
    GROUP BY 
        sh.ShipmentID

我收到错误代码:

  

Column' Shipments.ShipmentOrderDate'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。

我是否需要将sh.ShipOrderDate添加到GROUP BY?如果是这样,为什么会这样?

3 个答案:

答案 0 :(得分:1)

您必须在条款中包含“Shipments.ShipmentOrderDate”。 在Group By子句中包含非操作列是必要的。

import functools as ft #<------ used to keep meth-related docstring

class Cache(object):
    def __init__(self):
        self._cache = {}

    @classmethod
    def _property(cls, meth):
        @property
        @ft.wraps(meth)
        def __property(cls):
            meth_name = meth.__name__
            if meth_name not in cls._cache:
                cls._cache[meth_name] = meth(cls)
            return cls._cache[meth_name]
        return __property

    @classmethod
    def _method(cls, meth):
        @ft.wraps(meth)
        def __method(cls, *args, **kwargs):
            meth_key = '{}_{}'.format(meth.__name__, args)# <---- considered as string so as avoid unhashable-type errors
            if meth_key not in cls._cache:
                cls._cache[meth_key] = meth(cls, *args, **kwargs)
            return cls._cache[meth_key]
        return __method

答案 1 :(得分:1)

  

错误代码:列&#39; Shipments.ShipmentOrderDate&#39;是无效的   选择列表,因为它不包含在聚合中   函数或GROUP BY子句。

     

我是否需要将sh.ShipOrderDate添加到GROUP BY?如果是这样的话   此?

排序答案是:

这是你的select子句(重新格式化)。列已被排列成2段1.&#34;非聚合&#34;列和2.&#34;聚合&#34;使用聚合函数的列,如SUM / COUNT / MIN / MAX / AVG等

SELECT
  -- "non-aggregating columns"
  sh.ShipmentID, sh.ShipmentOrderDate, sh.TaxAmount
, sh.ShipDate, si.ShipItemPrice, si.ShipItemDiscountAmount
, si.Quantity, b.BrandName
-- "aggregating columns"
, SUM(si.ShipItemPrice - si.ShipItemDiscountAmount) As FinalPrice
, SUM((si.ShipItemPrice - si.ShipItemDiscountAmount) * si.Quantity) AS ItemTotal

现在重新阅读错误消息:because it is not contained in either an aggregate function or the GROUP BY clause.这意味着:

  1. 删除&#34;非聚合&#34; select子句中的列,或
  2. 添加&#34;非聚合&#34;列进入GROUP BY子句
  3. 最终你会发现ALL&#34;非聚合&#34;列必须列在GROUP BY子句中,如下所示:

    CREATE VIEW ShipItemsBrand AS 
    SELECT
          -- "non-aggregating columns"
          sh.ShipmentID, sh.ShipmentOrderDate, sh.TaxAmount
        , sh.ShipDate, si.ShipItemPrice, si.ShipItemDiscountAmount
        , si.Quantity, b.BrandName
        -- "aggregating columns"
        , SUM(si.ShipItemPrice - si.ShipItemDiscountAmount) As FinalPrice
        , SUM((si.ShipItemPrice - si.ShipItemDiscountAmount) * si.Quantity) AS ItemTotal
    FROM Brands AS b 
        JOIN ShipItems AS si ON b.BrandID = si.BrandID
        JOIN Shipments AS sh ON si.ShipmentID = sh.ShipmentID
    GROUP BY
          -- "non-aggregating columns"
          sh.ShipmentID, sh.ShipmentOrderDate, sh.TaxAmount
        , sh.ShipDate, si.ShipItemPrice, si.ShipItemDiscountAmount
        , si.Quantity, b.BrandName
    

    提示:将您的select子句条目排列到2个部分中,然后在group by下复制/粘贴非聚合列。 nb:在粘贴后删除所有列别名

    注意:在旧版本的MySQL中,可以在group by子句中列出更少的非聚合列。然而,这是MySQL特有的,它不受SQL标准的支持。此外,最新版本的MySQL已经改变了默认行为,它也变得越来越符合标准。

答案 2 :(得分:0)

CREATE VIEW ShipItemsBrand AS 
SELECT sh.ShipmentID,sh.TaxAmount, sh.ShipDate,
si.ShipItemPrice, si.ShipItemDiscountAmount, SUM(si.ShipItemPrice - 
si.ShipItemDiscountAmount) As FinalPrice, si.Quantity, SUM((si.ShipItemPrice 
- si.ShipItemDiscountAmount) * si.Quantity) AS ItemTotal,
b.BrandName
FROM Brands AS b 
JOIN ShipItems AS si
    ON b.BrandID = si.BrandID
JOIN Shipments AS sh 
    ON si.ShipmentID = sh.ShipmentID
GROUP BY sh.ShipmentID

CREATE VIEW NewShipItemsBrand AS 
SELECT * from ShipItemsBrand left join Shipments on si.ShipmentID = 
sh.ShipmentID and sh.ShipmentOrderDate=si.ShipmentID