CREATE TABLE most_prof
(
pub_id CHAR(4) NOT NULL,
top_profit VARCHAR(80) NOT NULL,
date_time DATETIME,
PRIMARY KEY (top_profit)
)
INSERT INTO most_prof (pub_id, top_profit, date_time)
SELECT t.pub_id, t.title, t.pubdate
FROM titles AS t
这是家庭作业,所以我绝不要求答案,只是一些指导! 在具有t.title的select语句中,我需要返回与计算出的最高利润相关的标题。因此,我需要占用几列,计算最高利润,然后返回与之相关的标题。每个pub_id都有多个与之关联的标题,但我只需要一个利润最高的标题和与之关联的pubdate。
我尝试了一些尝试,但是我不断收到此错误
列“ titles.pub_id”在选择列表中无效,因为该列既未包含在聚合函数中,也未包含在GROUP BY子句中。
由于这是家庭作业,请不要回答,只是尽可能寻求指导。
编辑:
在SELECT语句中,t.title返回一本书的标题,但是这必须是特定的标题。为了找到这一点,我需要使用表中的其他列来计算每个发布商的书名利润-类似于(((price-(royalty * 1.0 / 100))* ytd_sales)-advance。然后,我需要使用它来返回1个从每个发布商处获得最高利润的标题。
第二编辑:这就是给我上述错误的原因
INSERT INTO most_prof(pub_id, top_profit, date_time)
SELECT t.pub_id, (((price - (royalty * 1.0 / 100)) * ytd_sales) -
advance), t.pubdate
FROM titles AS t
GROUP BY t.title;
第三次编辑:
INSERT INTO most_prof (pub_id, top_profit, date_time)
SELECT DISTINCT
pub_id, MAX (((price - (royalty * 1.0 / 100)) * ytd_sales) - advance),
pubdate
FROM titles
GROUP BY pub_id
现在,这将返回pub_id,top_profit和发布日期:
我已经添加了到目前为止的内容的屏幕抓图-看起来不错。如您所见,每个pub_id都有多个标题-如何为三个pub_id的每个返回最赚钱的标题?
答案 0 :(得分:2)
首先,我要感谢您:
这是家庭作业,所以我绝不要求答案,只是一些 指导!
这:
由于这是家庭作业,请不要回答,只是寻找指导 尽你所能。
我将尝试做的是给您一些提示,以帮助您找到答案。
(根据给定的信息),我假设这是家庭作业,将使用聚合函数(例如SUM(),AVG(),MIN(),MAX()等),GROUP BY,(可能是HAVING)和排序依据。
请记住,每当使用聚合函数时,都需要指定SELECT下的列,并且GROUP BY子句中的聚合函数不包含这些列。
因此,如果您这样做:
SELECT t.pub_id, SUM(((price - (royalty * 1.0 / 100)) * ytd_sales) - advance), t.pubdate
FROM titles AS t
GROUP BY t.title;
它会给您一个错误,因为SELECT子句下没有t.title
。因此,正确的是这样的:
GROUP BY t.pub_id, t.pubdate
如果要将其按t.title分组,则需要执行以下操作:
SELECT t.title, SUM(((price - (royalty * 1.0 / 100)) * ytd_sales) - advance)
FROM titles AS t
GROUP BY t.title;
如果有一段规定的时间(例如您想获得每个标题的最近3个月的利润),则可以使用t.pubdate
,但这将在WHERE(或HAVING)子句下,而t.title
将在SELECT子句下。
现在,完成计算后,您需要按最高利润对结果进行重新排序,然后只需选择最高利润即可。某些人喜欢包含两个聚合函数(例如MIN(SUM(...))
)来获得最高或最低值,这比较容易,这样可以避免它们使用ORDER BY。
更新(基于评论)
由于您已经涵盖了子查询,因此您已经很接近答案了。
运行第二个标题查询后,我可以看到所有 标题及其利润,我似乎无法弄清楚如何建立关联 这些标题及其相应的pub_id。可以说我有3个 pub_id-和每个pub_id具有多个标题。我不知道如何 关联特定pub_id的top_profit标题(如果有) 有道理。
获取利润的正确方法是找到可用于汇总利润的唯一ID。对于您的情况,您说pub_id
有多个title
,那么,我假设pub_id
是主键,并且标题已分配给每个主键。 (例如,出版商可以出版多本书),因此您需要从所有已出版的图书中获取出版商的利润。
有了这个,您知道需要获取出版商而不是书籍。因此,在查询中,您需要将titles
替换为pub_id
,其余部分保持原样。这将基于pub_id
汇总所有利润,这是您需要的主要要求。
如果您需要获取每家出版商的书的利润,则可以使用
SELECT t.pub_id, t.title SUM(....) as Profit
FROM titles AS t
GROUP BY t.pub_id, t.title;
这就像告诉SQL一样:嘿,请问给出版商每本书的利润。这将为您带来每本书的利润。
但是,如果您这样做:
SELECT t.pub_id, SUM(....) as Profit
FROM titles AS t
GROUP BY t.pub_id;
它将为您带来每个出版商的利润(这意味着如果出版商有5本书,则将其相加)。
因此,您将在GROUP BY
和SUM()
中包括的更多列中进一步详细介绍。
如果您需要用子查询将其括起来,则有不同的方法来执行此操作,但我将为您提供两种方法。
方法一:
SELECT *
FROM (
SELECT t.pub_id, SUM(....) as Profit
FROM titles AS t
GROUP BY t.pub_id;
) D -- alias is mandatory
方法二:
SELECT *
FROM titles t1
JOIN (
SELECT t.pub_id, SUM(....) as Profit
FROM titles AS t
GROUP BY t.pub_id;
) t2 ON t1.pub_id = t2.pub_id
因此,您可以根据需要使用方法一或方法二。
更新(基于评论)#2
我已经添加了到目前为止的内容的屏幕抓图-看起来不错。 如您所见,每个pub_id都有多个标题-我该如何 仅返回3个pub_id的每一个收益最高的标题?
太好了,您快完成了。您需要使用名为ROW_NUMBER()
的函数根据我们的自定义条件对行进行编号。因此,我们将添加以下内容:
ROW_NUMBER() OVER(PARTITION BY t1.pub_id ORDER BY Profit DESC) AS ProfitOrder
新订单将按t1.pub_id进行分区,并对每个分区按最高到最低利润(对于每个id组)进行排序。
我们的查询应如下所示:
SELECT
t1.title
, t1.pub_id
, t1.pubdate
, Profit
, ROW_NUMBER() OVER(PARTITION BY t1.pub_id ORDER BY Profit DESC) AS ProfitOrder
FROM titles t1
JOIN (
SELECT t.pub_id, t.title, SUM(price * ytd_sales) as Profit
FROM titles AS t
GROUP BY t.pub_id
) t2 ON t1.pub_id = t2.pub_id
如果运行上述查询,则每个pub_id的ProfitOrder数字1将具有最高的Profit,这可以验证我们的记录是否正确排序,并且我们只需要使用ProfitOrder从每个组中获取前3行。 ,如果我们需要这样做:
SELECT
t1.title
, t1.pub_id
, t1.pubdate
, Profit
, ROW_NUMBER() OVER(PARTITION BY t1.pub_id ORDER BY Profit DESC) AS ProfitOrder
FROM titles t1
JOIN (
SELECT t.pub_id, t.title, SUM(price * ytd_sales) as Profit
FROM titles AS t
GROUP BY t.pub_id
) t2 ON t1.pub_id = t2.pub_id
WHERE
ProfitOrder <= 3
这将产生错误,因为除非将查询转换为子查询,否则我们无法在WHERE
下使用列别名。因此,我们需要再次将该查询包含在子查询中。像这样一个:
SELECT *
FROM (
SELECT
t1.title
, t1.pub_id
, t1.pubdate
, Profit
, ROW_NUMBER() OVER(PARTITION BY t1.pub_id ORDER BY Profit DESC) AS ProfitOrder
FROM titles t1
JOIN (
SELECT t.pub_id, t.title, SUM(price * ytd_sales) as Profit
FROM titles AS t
GROUP BY t.pub_id
) t2 ON t1.pub_id = t2.pub_id
) D
WHERE
ProfitOrder <= 3
现在,如果输出是您期望的结果,请再次验证记录。然后,您只需要使用顶部的SELECT *
并选择仅需要显示的列即可。像SELECT pub_id, Profit, pubdate
,然后将其包括在INSERT
下,但要确保INSERT和SELECT之间的列匹配。