大家好我执行此查询以获取一个表格,其中包含一些数据库信息的统计信息。我想要初始化不存在的字段(因为查询是在不同的日期执行的,有时候会有一天什么都没有)所以我希望它返回0和NULL(在TOP列中)
SELECT
SUM(IF(`TOP` = 'one',`Nb`,0)) as first_one,
SUM(IF(`TOP` = 'two',`Nb`,0)) as second_one,
SUM(IF(`TOP` = 'three',`Nb`,0)) as thrid_one,
SUM(IF(`TOP` NOT IN ('three','two','one'),`Nb`,0)) as forth_one,
GROUP_CONCAT(IF(`TOP` NOT IN ('three','two','one'),`TOP`,'') SEPARATOR '') as `OR`
FROM (
SELECT
COUNT(*) as Nb,
'one' as `TOP`
FROM
mytable
WHERE
TYPE = 'MSS'
AND YEAR(date) = YEAR(CURDATE())
AND MONTH(date) = MONTH(CURDATE())
UNION ALL
SELECT
COUNT(*) as Nb,
'two' as `TOP`
FROM
mytable
WHERE
TYPE = 'MSS'
AND S=0
AND YEAR(date) = YEAR(CURDATE())
AND MONTH(date) = MONTH(CURDATE())
UNION ALL
SELECT
COUNT(*) as Nb,
'three' as `TOP`
FROM
mytable
WHERE
TYPE = 'MSS'
AND S<>0
AND YEAR(date) = YEAR(CURDATE())
AND MONTH(date) = MONTH(CURDATE())
UNION ALL
SELECT
`Nb`,
`TOP`
FROM(
SELECT
COUNT(*) as Nb ,
`OR` as `TOP`
FROM
mytable
WHERE
TYPE = 'MSS'
AND YEAR(date) = YEAR(CURDATE())
AND MONTH(date) = MONTH(CURDATE())
GROUP BY
`OR`
ORDER BY
Nb DESC
LIMIT 1
) as tmp
)as tmp1
答案 0 :(得分:1)
假设在tmp1
中你需要数据但是有“空白”(根本没有数据的天数)你可以使用{{1} RIGHT JOIN
tmp1到表tmp2
(我假设你在day
表中有这样的列)。所以tmp1
只是日期列表:
tmp2
如果您想提供数据库架构,我可以详细说明我的答案。
答案 1 :(得分:0)
您可以将每个子查询替换为:
SELECT
IFNULL(tmp.Nb,0) as Nb,
IFNULL(tmp.`TOP`, 'value') as `TOP`
FROM (
--subquery
) as tmp
第一个子查询的示例:
SELECT
IFNULL(tmp.Nb,0) as Nb,
IFNULL(tmp.`TOP`, 'one') as `TOP`
FROM (
SELECT
COUNT(*) as Nb,
'one' as `TOP`
FROM
mytable
WHERE
TYPE = 'MSS'
AND YEAR(date) = YEAR(CURDATE())
AND MONTH(date) = MONTH(CURDATE())
) as tmp
答案 2 :(得分:0)
SQL擅长将现有实体分组为类别,但不善于“创建”实体本身。如果您还有非日期类别,或者Wiktor建议使用日期表,那么我会建议使用通用数字表(实际上只是从0到数十万的数字),并且在接下来的几年里以及你的计划工作以来的时间。
使用日期表
list_dates (
id int(11) not null primary key auto_increment,
dateval date not null
)
您可以从该表开始查询(当然,范围合理)并计算其他所有内容:
select list_dates.dateval as date, count(*) as cnt
from list_dates
left join actions on actions.actiontime >= (cast list_dates.date_val as datetime)
and actions.actiontime < (cast list_dates.date_val `interval 1 day as datetime)
where list_dates.dateval between '$fromDate' and '$toDate'
group by list_dates.dateval
;
或以数字表编号
开头select $fromDate + interval numbers.number day as date, count(*) as cnt
from numbers
left join actions
on actions.actiontime >= (cast $fromDate + interval numbers.number day as datetime)
and actions.actiontime < (cast $fromDate + interval (1 + numbers.number) day as datetime)
where numbers.number >= 0 and numbers.number < $countDates
group by numbers.number
;
如果你真的只想要那一天(今天)那么你当然可以使用匿名子选择 - 表,所以它变成了
select list_dates.dateval as date, count(*) as cnt
from ( select curdate() as dateval ) as list_dates
left join actions on actions.actiontime >= (cast list_dates.date_val as datetime)
and actions.actiontime < (cast list_dates.date_val `interval 1 day as datetime)
where list_dates.dateval between '$fromDate' and '$toDate'
group by list_dates.dateval
;