【问题标题】:How to modify query to walk entire table rather than a single如何修改查询以遍历整个表而不是单个表
【发布时间】:2017-03-08 17:35:58
【问题描述】:

我编写了几个 SQL 查询并针对我的表执行它们。每个单独的查询都有效。我一直在添加功能,直到我得到一个非常丑陋的工作查询。问题是每次我想使用它时都必须手动更改一个值。您能协助使这个查询自动而不是“手动”吗?

我正在使用 DB2。

下表显示了从 1 到 3 的客户 (cid)。“club”是书商,“qnty”是客户从每个“club”购买的书籍数量。满桌有 45 位顾客。

下图显示了前 3 个用户的所有表格元素(cid=1 OR cid=2 OR cid=3)。我所有查询的最终目的(一旦合并)是为每个“cid”找到具有最大“qnty”的单个“俱乐部”。因此,对于“cid =1”,“club”是读者文摘,“qnty”为 3。对于“cid=2”,“club”是 YRB Gold,“qnty”为 5。一直持续到 cid 45。

为了让您了解我在这里所做的事情的背景,是我的疑问:

(查询1-cid=1的起点)

SELECT * FROM yrb_purchase WHERE cid=1

(查询 2 - 找到 cid=1 的 'qnty' 最高的 'club')

SELECT *
FROM
(SELECT club,
        sum(qnty) AS t_qnty
FROM yrb_purchase
WHERE cid=1
GROUP BY club)results
ORDER BY t_qnty DESC

(查询 3 - 将上述查询中的记录与其 cid 结合起来)

SELECT cid,
    temp.club,
    temp.t_qnty
FROM yrb_purchase AS p,

(SELECT *
FROM
    (SELECT club,
            sum(qnty) AS t_qnty
    FROM yrb_purchase
    WHERE cid=1
    GROUP BY club)results
ORDER BY t_qnty DESC FETCH FIRST 1 ROWS ONLY) AS TEMP
WHERE p.cid=1
AND p.club=temp.club

(查询 4)确保 cid=1 只有一条记录

SELECT cid,
    temp.club,
    temp.t_qnty
FROM yrb_purchase AS p,

(SELECT *
FROM
    (SELECT club,
            sum(qnty) AS t_qnty
    FROM yrb_purchase
    WHERE cid=1
    GROUP BY club)results
ORDER BY t_qnty DESC FETCH FIRST 1 ROWS ONLY) AS TEMP
WHERE p.cid=1
AND p.club=temp.club FETCH FIRST ROWS ONLY

要获得客户 2 的“qnty”最高的“俱乐部”,我只需在上面的最后一个查询中将文本 cid=1 更改为 cid=2。我的查询似乎总是产生正确的结果。我的问题是,如何修改查询以获取单个表中从 1 到 45 的所有“cid”的结果?我如何获得一张包含所有 cid 值的桌子以及出售该 cid 书籍最多的俱乐部,以及一张桌子内出售了多少本书?请记住,我希望您可以修改我的查询,而不是您提供更好的查询。

如果您认为我的查询太难看(我同意您的观点)并选择提供另一个查询,请注意我刚刚开始学习 SQL,可能无法理解您的查询。您应该知道我已经问过这个问题:For common elements, how to find the value based on two columns? SQL 但我无法做出答案(由于我的 SQL 限制 - 不是因为答案不好);在没有有效答案的情况下,我无法对其进行逆向工程以了解它是如何工作的。 提前致谢

****************************编辑#1**************** ****************************** 答案的结果是:

【问题讨论】:

标签: sql db2


【解决方案1】:

您可以使用 OLAP/窗口函数来实现:

SELECT
    cid,
    club,
    qnty
FROM
    (
        SELECT
            cid,
            club,
            qnty,
            ROW_NUMBER() OVER (PARTITION BY cid order by qnty desc) as cid_club_rank
        FROM
            (
                SELECT 
                    cid,
                    club, 
                    sum(qnty) as qnty   
                FROM yrb_purchase 
                GROUP BY cid, club
            ) as sub1
    ) as sub2
WHERE cid_club_rank = 1

最里面的语句 (sub1) 只是获取每个 cid/club 组合的总数量。第二个最里面的语句(sub2)为每个按数量排序的 cid/club 组合创建一个 row_number(自上而下)。然后最外面的查询只选择 row_number() 为 1 的记录。

【讨论】:

  • 感谢您的帮助!当我运行您的查询时,出现错误。消息是:SQL0104N An unexpected token "yrb_purchase" was found following "(qnty) as qnty, FROM". Expected tokens may include: "FROM". SQLSTATE=42601 有什么建议吗?
  • 对不起,里面有一个逗号。
  • 很抱歉一直打扰您...我正在努力使答案起作用,但我一直在碰壁,我不明白。现在是错误SQL0440N No authorized routine named "SUB" of type "FUNCTION" having compatible arguments was found. SQLSTATE=42884。我试图在网上找到sub() 函数来理解它,但奇怪的是,我运气不佳。再次感谢您的宝贵时间!
  • 对不起。很多脂肪指法发生。那应该是sum()。我已经更新了查询。不用担心问题!
  • 感谢您让我明白这一点!我将查询结果的图像作为“编辑#1”放在帖子正文中。需要对查询进行哪些修改才能为每个“cid”(具有最大“qnty”的“俱乐部”)只给我一个“俱乐部”和“qnty”?
猜你喜欢
  • 1970-01-01
  • 2019-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-05
  • 1970-01-01
  • 2018-01-15
相关资源
最近更新 更多