最近在开发一个公司内部使用的财务报表系统,在一次查询时数据库报了一个错误,在网上查看原因并解决问题之后顺便记录一下,该sql的目标是从日报主表,日报月数据表,日报模块表中查询到指定经营公司,指定日期的当日汇总数据(包含部分当月数据用于后续计算)
问题sql如下:
SELECT
A1.depcode AS depcode,
SUM(d_dd_xcddsntq) AS sntq,
(
SELECT
(
SUM(d_jk_scddldl) + SUM(d_jk_zcddldl) + SUM(d_jk_hdjkl)
) AS bysj
FROM
mall_daily A
LEFT JOIN mall_daily_jk B ON A.id = B.d_id
LEFT JOIN mall_daily_month C ON A.depcode = C.depcode
AND A.d_datetime >= C. START
AND A.d_datetime <= C.
END
WHERE
A.d_date >= DATE_FORMAT('2018-03-01', '%Y-%m-%d')
AND A.d_date <= DATE_FORMAT('2018-03-21', '%Y-%m-%d')
AND A.depcode = A1.depcode
) AS aj13,
(
SELECT
SUM(B.d_dd_xcztdd) AS bysj
FROM
mall_daily A
LEFT JOIN mall_daily_dd B ON A.id = B.d_id
LEFT JOIN mall_daily_month C ON A.depcode = C.depcode
AND A.d_datetime >= C. START
AND A.d_datetime <= C.
END
WHERE
A.d_date >= DATE_FORMAT('2018-03-01', '%Y-%m-%d')
AND A.d_date <= DATE_FORMAT('2018-03-21', '%Y-%m-%d')
AND C.table_name = 'DailyDd'
AND A.depcode = A1.depcode
) AS aj25,
TRUNCATE (
(SELECT aj25) / (SELECT aj13),
2
) AS bysj,
D.d_month_byjh AS byjh,
TRUNCATE (
(SELECT bysj) / (SELECT byjh),
2
) AS jhdcl,
TRUNCATE (30 / 31, 2) AS sjjd,
TRUNCATE (
(SELECT bysj) / (SELECT sntq),
2
) AS tb
FROM
mall_daily A1
LEFT JOIN mall_daily_dd B ON A1.id = B.d_id
LEFT JOIN mall_daily_jk C ON A1.id = C.d_id
LEFT JOIN mall_daily_month D ON A1.depcode = D.depcode
AND A1.d_datetime >= D. START
AND A1.d_datetime <= D.
END
WHERE
A1.d_date >= DATE_FORMAT('2018-03-01', '%Y-%m-%d')
AND A1.d_date <= DATE_FORMAT('2018-03-21', '%Y-%m-%d')
GROUP BY
A1.depcode;上述sql在执行时提示
[Err] 1247 - Reference 'sntq' not supported (reference to group function)大意是不支持'sntq'的引用,但是上面SELECT的字段中明明有这个alias。后来临时通过在这个位置用表达式替换了别名解决(将SELECT sntq替换为SUM(d_dd_xcddsntq)),但始终觉得不完美,最后google以下找到了更好的解决方式,就是在这个查询语句外层再套一层查询语句,也就是将当前查询语句作为另一个语句的子查询,修改后结构如下:
SELECT
depcode,
sntq,
bysj,
byjh,
jhdcl,
sjjd,
TRUNCATE (bysj / sntq, 2) AS tb
FROM
(
SELECT
A1.depcode AS depcode,
SUM(d_dd_xcddsntq) AS sntq,
(
SELECT
(
SUM(d_jk_scddldl) + SUM(d_jk_zcddldl) + SUM(d_jk_hdjkl)
) AS bysj
FROM
mall_daily A
LEFT JOIN mall_daily_jk B ON A.id = B.d_id
LEFT JOIN mall_daily_month C ON A.depcode = C.depcode
AND A.d_datetime >= C. START
AND A.d_datetime <= C.
END
WHERE
A.d_date >= DATE_FORMAT('2018-03-01', '%Y-%m-%d')
AND A.d_date <= DATE_FORMAT('2018-03-21', '%Y-%m-%d')
AND A.depcode = A1.depcode
) AS aj13,
(
SELECT
SUM(B.d_dd_xcztdd) AS bysj
FROM
mall_daily A
LEFT JOIN mall_daily_dd B ON A.id = B.d_id
LEFT JOIN mall_daily_month C ON A.depcode = C.depcode
AND A.d_datetime >= C. START
AND A.d_datetime <= C.
END
WHERE
A.d_date >= DATE_FORMAT('2018-03-01', '%Y-%m-%d')
AND A.d_date <= DATE_FORMAT('2018-03-21', '%Y-%m-%d')
AND C.table_name = 'DailyDd'
AND A.depcode = A1.depcode
) AS aj25,
TRUNCATE (
(SELECT aj25) / (SELECT aj13),
2
) AS bysj,
D.d_month_byjh AS byjh,
TRUNCATE (
(SELECT bysj) / (SELECT byjh),
2
) AS jhdcl,
TRUNCATE (30 / 31, 2) AS sjjd
FROM
mall_daily A1
LEFT JOIN mall_daily_dd B ON A1.id = B.d_id
LEFT JOIN mall_daily_jk C ON A1.id = C.d_id
LEFT JOIN mall_daily_month D ON A1.depcode = D.depcode
AND A1.d_datetime >= D. START
AND A1.d_datetime <= D.
END
WHERE
A1.d_date >= DATE_FORMAT('2018-03-01', '%Y-%m-%d')
AND A1.d_date <= DATE_FORMAT('2018-03-21', '%Y-%m-%d')
GROUP BY
A1.depcode
) t;