RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1590438
Accepted
dofi4ka
dofi4ka
Asked:2024-08-13 06:06:22 +0000 UTC2024-08-13 06:06:22 +0000 UTC 2024-08-13 06:06:22 +0000 UTC

SQL查询优化

  • 772

我在统一国家考试中发现了一项关于使用 sqlite3 处理数据库的有趣任务 问题情况

我不假思索地写了这个查询,它给出了正确的答案30%

SELECT SUM(products_moving.quantity * products_moving.cost) * 100 / (
    SELECT SUM(products_moving.quantity * products_moving.cost) FROM products_moving
    JOIN shops ON products_moving.shop_id = shops.id
    WHERE products_moving.op_type = 'Продажа'
        AND shops.region = 'Октябрьский'
) FROM products_moving
JOIN products ON products_moving.article = products.article
JOIN shops ON products_moving.shop_id = shops.id
WHERE products_moving.op_type = 'Продажа'
    AND shops.region = 'Октябрьский'
    AND products.type = 'Молоко'

但这远不是最完美的解决方案,因为理论上,我会在数据库中搜索两次十月镇地区的所有销售情况。我变得非常感兴趣,是否有可能以某种方式把它画得更漂亮、更优雅query?

我想到的第一件事是首先找到十月地区的所有销售额,将它们保存在某个地方,以卢布计算其金额,将该金额保存在某个地方,然后从之前保存的十月地区所有销售额的集合中,仅计数所有拥有“牛奶”类别的人,找到其金额(以卢布为单位)并计算百分比

那些。做类似这样的事情,但是在 SQL 中:

sales_in_region = filter(
    lambda row: row["op_type"] == 'Продажа' and row["region"] == 'Октябрьский',
    all_rows
)

sales_in_region_sum = sum(map(
    lambda row: row["quantity"] * row["cost"],
    sales_in_region
))

sales_in_region_milk = filter(
    lambda row: row["type"] == 'Молоко',
    sales_in_region
)

sales_in_region_milk_sum = sum(map(
    lambda row: row["quantity"] * row["cost"],
    sales_in_region_milk
))

print(sales_in_region_milk_sum // sales_in_region_sum * 100)

当然,在统一国家考试的框架内,优化这个查询是没有意义的,因为我不会多次这样做,即使需要十秒钟,我也不必担心,但我想知道是否有一种方法可以以某种方式完美地处理此类情况?

UPD:在下面的答案中,我们详细讨论了WITH AS运算符的想法,我在上面暗示过,但是从不同的角度看问题,我想出了一个不同的解决方案,该解决方案已经明显更快

SELECT 
    SUM(CASE WHEN products.type = 'Молоко' THEN products_moving.quantity * products_moving.cost END) 
    * 100 /  SUM(products_moving.quantity * products_moving.cost)
FROM products_moving
JOIN products ON products_moving.article = products.article
JOIN shops ON products_moving.shop_id = shops.id
WHERE products_moving.op_type = 'Продажа'
    AND shops.region = 'Октябрьский'

这个想法是使用 CASE 运算符来过滤 SUM 中所需的行

python
  • 2 2 个回答
  • 61 Views

2 个回答

  • Voted
  1. dofi4ka
    2024-08-13T18:32:57Z2024-08-13T18:32:57Z

    考虑到评论中的所有要点,此查询将返回整数百分比,如果找不到合适的记录,则返回 null

    SELECT 
        SUM((products.type = 'Молоко') * products_moving.quantity * products_moving.cost) 
        * 100 / NULLIF(SUM(products_moving.quantity * products_moving.cost), 0)
    FROM products_moving
    JOIN products ON products_moving.article = products.article
    JOIN shops ON products_moving.shop_id = shops.id
    WHERE products_moving.op_type = 'Продажа'
        AND shops.region = 'Октябрьский'
    
    • 2
  2. Best Answer
    AnnaBazueva - SPAM
    2024-08-13T06:38:30Z2024-08-13T06:38:30Z

    是的,你可以这样做:

    WITH total_sales AS (
        SELECT SUM(products_moving.quantity * products_moving.cost) AS total
        FROM products_moving
        JOIN shops ON products_moving.shop_id = shops.id
        WHERE products_moving.op_type = 'Продажа'
            AND shops.region = 'Октябрьский'
    )
    SELECT SUM(products_moving.quantity * products_moving.cost) * 100 / total_sales.total
    FROM products_moving
    JOIN products ON products_moving.article = products.article
    JOIN shops ON products_moving.shop_id = shops.id
    CROSS JOIN total_sales
    WHERE products_moving.op_type = 'Продажа'
        AND shops.region = 'Октябрьский'
        AND products.type = 'Молоко';
    

    WITH查询(公用表表达式)



    CASE 添加了使用inside 的 选项 SUM

    SELECT 
        SUM(CASE 
                WHEN products.type = 'Молоко' THEN products_moving.quantity * products_moving.cost 
                ELSE 0 
            END) * 100 / NULLIF(SUM(CASE 
                                        WHEN shops.region = 'Октябрьский' AND products_moving.op_type = 'Продажа' THEN products_moving.quantity * products_moving.cost 
                                        ELSE 0 
                                    END), 0) AS milk_sales_percentage
    FROM products_moving
    JOIN products ON products_moving.article = products.article
    JOIN shops ON products_moving.shop_id = shops.id
    WHERE products_moving.op_type = 'Продажа'
        AND shops.region = 'Октябрьский';
    

    条件表达式CASE(条件聚合)

    • 1

相关问题

  • 是否可以以某种方式自定义 QTabWidget?

  • telebot.anihelper.ApiException 错误

  • Python。检查一个数字是否是 3 的幂。输出 无

  • 解析多个响应

  • 交换两个数组的元素,以便它们的新内容也反转

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5