0

我已经花了很长时间试图为我得到的这个 SUM 查询找到一个解决方案:

SELECT o.id, o.ordernr, o.datetime, o.status, CONVERT(ROUND(o.shipping,2), CHAR(8)) AS shippingcosts, 
u.id AS uid, u.name, u.surname, u.address, u.number, u.zipcode, u.country, u.email, 
GROUP_CONCAT(CONVERT(op.amount, CHAR(8))) AS amount,         
GROUP_CONCAT(CONVERT(ROUND(op.pprice,2), CHAR(8))) AS pprice, 

IF(     
        u.country!= 'NL', 
        ROUND(SUM(
            CASE
                WHEN op.discount > 0 THEN ((op.amount * op.pprice) - ((op.amount * op.pprice) * (op.discount/100)))
                WHEN op.discountf > 0 THEN ((op.amount * op.pprice) - ((op.amount * op.pprice) * (op.discountf/100)))
                WHEN op.discountf = 0 && op.discount = 0 THEN (op.amount * op.pprice)
            END
        ) + o.shipping,2),
        ROUND((SUM(
            CASE
                WHEN op.discount > 0 THEN ((op.amount * op.pprice) - ((op.amount * op.pprice) * (op.discount/100)))
                WHEN op.discountf > 0 THEN ((op.amount * op.pprice) - ((op.amount * op.pprice) * (op.discountf/100)))
                WHEN op.discountf = 0 && op.discount = 0 THEN ((op.amount * op.pprice)*1.19)
            END
        )*1.19) + o.shipping,2)
) AS total, 

GROUP_CONCAT(CONVERT(p.id, CHAR(8))) AS pid, 
SUM(p.weight) AS weight, 
FROM orders AS o
INNER JOIN users AS u ON o.uid = u.id 
INNER JOIN order_products AS op ON op.oid = o.id
INNER JOIN products AS p ON op.pid = p.id
GROUP BY o.id

我想要实现的是,如果 op.discount 不为空或 op.discountf 不为空,并且对于 op.discount 和 op.discountf 都为空的每一行,则获取每一行的总和......

在这一点上,mysql似乎正在对所有总数求和..??

有人可以帮我一把吗??

Thnx提前(很多)

4

2 回答 2

0

只是我在这里注意到的一些事情......

--您正在将所有整数或浮点数据类型转换为字符?你希望 MySQL 如何对字符求和?

SELECT o.id, o.ordernr, o.datetime, o.status, CONVERT(ROUND(o.shipping,2), CHAR(8)) AS shippingcosts, 
u.id AS uid, u.name, u.surname, u.address, u.number, u.zipcode, u.country, u.email, 
GROUP_CONCAT(CONVERT(op.amount, CHAR(8))) AS amount,         
GROUP_CONCAT(CONVERT(ROUND(op.pprice,2), CHAR(8))) AS pprice, 

-- 从未见过 group_concat 中的 CONVERT 函数,这是参考手册显示的代码 GROUP_CONCAT([DISTINCT] expr [,expr ...] [ORDER BY {unsigned_integer | col_name | expr} [ASC | DESC] [,col_name ...]] [SEPARATOR str_val]) -- 另外,如果你继续四舍五入,你不会得到正确的结果,只是把它扔在那里不确定你是否关心。我认为有太多的聚合正在进行,并且这可能会令人困惑。

IF(     
    u.country!= 'NL', 

——你不是已经在你的选择中四舍五入了吗?你需要在这里再圆吗?-- 每行是否也可能有折扣和折扣?如果它们两者都有,它们将适合您的前两个 CASE 结构,两次... - 看起来您还想要基于重量的运输成本,

    ROUND(SUM(
        CASE
            WHEN op.discount > 0 THEN ((op.amount * op.pprice) - ((op.amount * op.pprice) * (op.discount/100)))
            WHEN op.discountf > 0 THEN ((op.amount * op.pprice) - ((op.amount * op.pprice) * (op.discountf/100)))
            WHEN op.discountf = 0 && op.discount = 0 THEN (op.amount * op.pprice)
        END) + o.shipping,2),

-- 为什么你两次运行相同的 CASE 结构?一个要加*1.19?

    ROUND((SUM(
        CASE
            WHEN op.discount > 0 THEN ((op.amount * op.pprice) - ((op.amount * op.pprice) * (op.discount/100)))
            WHEN op.discountf > 0 THEN ((op.amount * op.pprice) - ((op.amount * op.pprice) * (op.discountf/100)))
            WHEN op.discountf = 0 && op.discount = 0 THEN ((op.amount * op.pprice)*1.19)
        END)*1.19) + o.shipping,2)
) AS total, 

GROUP_CONCAT(CONVERT(p.id, CHAR(8))) AS pid, 
SUM(p.weight) AS weight, 
FROM orders AS o
INNER JOIN users AS u ON o.uid = u.id 
INNER JOIN order_products AS op ON op.oid = o.id
INNER JOIN products AS p ON op.pid = p.id
GROUP BY o.id

我个人会尝试做这样的事情(可能只是调整内部连接不起作用):

SELECT * FROM products as p
(SELECT o.id, o.ordernr, o.datetime, o.status, CONVERT(ROUND(o.shipping, 2), CHAR(8)) AS     ShippingCosts,
u.id AS U_ID, u.name, u.surname, u.address, u.number, u.zipcode, u.coutnry, u.email, 
op.amount as Amount, op.pprice as Price, 
SUM((op.amount * op.pprice)-(op.discount/100)) as SubTotal, 
SUM((op.amount * op.pprice)-(op.discountf/100)) as SubTotal2,
SUM(p.weight * o.shipping) as Shipping_Charges,
SUM(SubTotal + SubTotal2 + Shipping_Charges)) as o
inner join users AS u ON o.U_ID = u.id
WHERE u.country != 'NL';

-- 抱歉,我意识到现在有 3 个内部连接。我会将所有这些总和汇总到另一个表中,上面写着

SELECT Order Number Order ID Order Date from Orders as O inner join Order Products as OP ON Order ID = 订单产品 ID 或订单 ID 中的任意一个,总和(小计),按订单 ID 分组;

创建一个表来保存这些字段,然后只对与订单号或订单 ID 对应的 user_ID 进行内部连接,应该在某处有一个外键以使连接更容易

SELECT Order Id, Order Number, Order DATE, Order Shipping, Order Product, Order Amount, SUM(Order SubTotal) FROM Orders_Total internal join users as U on o.U_ID = u.id

我没有考虑到听起来像是客户端可以做的一些前端事情的舍入或组转换,但计算很简单,但我真的很喜欢你的查询,我只是想为你分解它,对不起,这里有很多。

于 2012-06-11T15:46:51.947 回答
0

您说,“我想要实现的是,如果 op.discount 不为 null 或 op.discountf 不为 null 并且对于 op.discount 和 op.discountf 都为 null 的每一行,则获取每一行的总和。 ..” 如果是这种情况,我建议在您的 case 语句的 WHEN 条件中添加条件,专门测试 NULL 值,而不是将 op.discount 和 op.discountf 视为它们持有的值在与0. 又名,“NULL < 0”的计算结果为 NULL,而不是零……我不确定这将如何影响您的案例陈述?可以在此处找到有关在控制语句中使用 NULL 值的详细信息。

当我第一次看到这个查询时,我想我可能会反对它的存在……但在我仔细观察之后,我实际上并没有被冒犯。这没什么好说的,因为我喜欢写这样的查询。可能有一种更清洁的方式来做你正在做的事情,但我不明白为什么你的方式不应该工作。我确实在这一行的末尾看到了一个逗号:

SUM(p.weight) AS weight,

...我认为你不想在那里?我重新格式化了查询......不是更好,只是有点不同。帮助我更清楚地看到你在做什么。可能对其他人有帮助,所以我将其包括在下面。其他人可能不喜欢这种格式,所以我没有把它作为对问题的编辑来介绍。现在发布这个答案是因为我到目前为止所做/注意到的事情可能会帮助其他人。如果/当我看到其他任何内容时,将进行编辑以改进我的“答案”。

SELECT
    o.id,
    o.ordernr,
    o.datetime,
    o.status,
    CONVERT(ROUND(o.shipping,2), CHAR(8)) AS shippingcosts, 
    u.id AS uid,
    u.name,
    u.surname,
    u.address,
    u.number,
    u.zipcode,
    u.country,
    u.email, 
    GROUP_CONCAT(CONVERT(op.amount, CHAR(8))) AS amount,         
    GROUP_CONCAT(CONVERT(ROUND(op.pprice, 2), CHAR(8))) AS pprice, 
    IF(     
        u.country != 'NL', 
        ROUND(SUM(
            CASE
                WHEN op.discount > 0 THEN ((op.amount * op.pprice) - ((op.amount * op.pprice) * (op.discount / 100)))
                WHEN op.discountf > 0 THEN ((op.amount * op.pprice) - ((op.amount * op.pprice) * (op.discountf / 100)))
                WHEN op.discountf = 0 && op.discount = 0 THEN (op.amount * op.pprice)
            END
        ) + o.shipping, 2),
        ROUND((SUM(
            CASE
                WHEN op.discount > 0 THEN ((op.amount * op.pprice) - ((op.amount * op.pprice) * (op.discount / 100)))
                WHEN op.discountf > 0 THEN ((op.amount * op.pprice) - ((op.amount * op.pprice) * (op.discountf / 100)))
                WHEN op.discountf = 0 && op.discount = 0 THEN ((op.amount * op.pprice) * 1.19)
            END
        ) * 1.19) + o.shipping, 2)
    ) AS total, 
    GROUP_CONCAT(CONVERT(p.id, CHAR(8))) AS pid, 
    SUM(p.weight) AS weight,
FROM
    orders o INNER JOIN users u
        ON o.uid = u.id 
    INNER JOIN order_products op
        ON o.id = op.oid
    INNER JOIN products p
        ON op.pid = p.id
GROUP BY o.id
于 2012-06-11T16:02:19.483 回答