我现在花了很多年时间试图为我得到的这个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不为null或op.discountf不为null,并且op.discount和op.discountf都为null的每一行,则获取每一行的总和。
此时似乎mysql正在总结所有总数...... ??
有人可以帮助我吗?
Thnx提前(很多)
答案 0 :(得分: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订单编号订单ID订单日期从订单为O. 内部连接订购产品为OP ON订单ID =订购产品ID或订单ID,以SUM(小计), 按订单ID分组;
创建一个表来保存这些字段然后只需对应于订单号或订单ID的user_ID进行内部联接,应该有一个外键可以使联接更容易
SELECT订单ID,订单号,订单日期,订单发货,订单产品,订单金额,SUM(订单子总计)FROM Orders_Total 内联接用户为U.U_ID = u.id
上的U.我没有考虑到舍入或组转换,这听起来像客户端可以做的一些前端工作,但计算很简单,但我真的喜欢你的查询,我只是想把它分解对你而言,抱歉这里有很多。
答案 1 :(得分:0)
你说,“我想要实现的是,如果op.discount不为null或op.discountf不为null,并且op.discount和op.discountf的每一行都得到每行的总和是空的......“如果是这种情况,我建议在case语句的WHEN条件中添加条件,专门针对NULL值进行测试,而不是将op.discount和op.discountf视为保存值,这些值将相应地进行评估当与0比较时,“NULL< 0”评估为NULL,而不是零......我不确定这将如何影响你的case语句?可以在here找到有关在控制语句中使用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