我在这里很新,我正在修补MYSQL以获得一种支点表。
现在我在这里被封锁了:
SELECT `range`,
Sum(IF(`Vrange` = '< 5',1,0)) as `<5`,
Sum(IF(`Vrange` = ' 5-10',1,0)) as `5-10`,
Sum(IF(`Vrange` = ' 10-15',1,0)) as `10-15`,
Sum(IF(`Vrange` = ' 15-20',1,0)) as `15-20`,
Sum(IF(`Vrange` = ' 20-25',1,0)) as `20-25`,
Sum(IF(`Vrange` = ' 20-25',1,0)) as `20-25`,
Sum(IF(`Vrange` = '> 30',1,0)) as `>30`
FROM(
select `Time`,`HDG`, `Vitesse`,
case
when `HDG` between 1 and 90 then ' 0-90'
when `HDG` between 91 and 180 then ' 91-180'
when `HDG` between 181 and 270 then ' 181-270'
else '271-360'
end as `range`,
case
when `Vitesse` between 0 and 5 then '< 5'
when `Vitesse` between 6 and 10 then ' 5-10'
when `Vitesse` between 11 and 15 then ' 10-15'
when `Vitesse` between 16 and 20 then ' 15-20'
when `Vitesse` between 21 and 25 then ' 20-25'
when `Vitesse` between 25 and 30 then ' 25-30'
else '> 30'
end as `Vrange`
from DataPort
WHERE `Time` > now() - interval 1 day
ORDER BY `Time` DESC
)as SQ
GROUP BY `range`;我得到了以下信息:
| range | <5 | 5-10 | ...
|---------|---------|------------|--------
| 0-90 | 5 | 3 |
| 180-270 | 12 | 20 |我想在每一行中显示所有范围的项目,即0-90 / 91-180 / 181-270 / 271-360。怎么可能?详情如下:
| range | <5 | 5-10 | ...
|---------|---------|------------|--------
| 0-90 | 1 | 1 |
| 91-180 |0 or null| 0 or null |
| 180-270 | 12 | 20 |
| 271-360 |0 or null| 0 or null |事先非常感谢
发布于 2021-12-15 19:21:28
欢迎来到S/O,这将有助于得到你所拥有的。您不需要执行显式的预查询来获取范围,然后在外部查询中再次对计数进行求和。
select
AllRanges.Required Range,
sum( case when DP.Vitesse >= 0 and DP.Vitesse < 5 then 1 else 0 end ) ' < 5',
sum( case when DP.Vitesse >= 5 and DP.Vitesse < 10 then 1 else 0 end ) '5-10',
sum( case when DP.Vitesse >= 10 and DP.Vitesse < 15 then 1 else 0 end ) '10-15',
sum( case when DP.Vitesse >= 15 and DP.Vitesse < 20 then 1 else 0 end ) '15-20',
sum( case when DP.Vitesse >= 20 and DP.Vitesse < 25 then 1 else 0 end ) '20-25',
sum( case when DP.Vitesse >= 25 and DP.Vitesse < 30 then 1 else 0 end ) '25-30',
sum( case when DP.Vitesse >= 30 then 1 else 0 end ) '>30'
from
( select '0-90' Required
UNION select '91-180'
UNION select '181-270'
UNION select '271-360' ) AllRanges
LEFT JOIN DataPort DP
ON AllRanges.Required =
case when DP.HDG >= 0 and DP.HDG <= 90 then '0-90'
when DP.HDG > 90 and DP.HDG <= 180 then '91-180'
when DP.HDG >= 180 and DP.HDG <= 270 then '181-270'
else '271-360' end
AND DP.`Time` > now() - interval 1 day
group by
case when DP.HDG >= 0 and DP.HDG <= 90 then '0-90'
when DP.HDG > 90 and DP.HDG <= 180 then '91-180'
when DP.HDG >= 180 and DP.HDG <= 270 then '181-270'
else '271-360' end现在,在说了这些话之后,我想指出其中一些不太理想的部分。
你的"HDG",我相信是一个定向航向,技术上永远是0-359度,因为360实际上是回到0。
在Vitesse范围括号中,不知道是否有小数/十进制值,但您要使用标签两次,如5-10和10-15。10不应该只在一个括号内吗?你的中间测试在11到15之间,所以标题组也应该匹配吗?
您的结果列应该命名为列。不是空格,特别是特殊字符、破折号等。结果应该是一个具有直接列名的表。它是输出的一部分,例如报表或web,其中有带有适当上下文的标题列,而不是在尝试时命名列。
最后,要小心您的列名,例如'Time',不要在SQL列定义中使用保留关键字。看看可用的命令、函数名等等,而不是仅仅是时间,可能是EntryTime、LogTime、CreateTime或类似的命令。更加明确的上下文,您将避免添加tick标记的一切。此外,通过使用table.column或alias.column进行限定,有助于防止在连接具有类似列名的多个表时出现歧义。
随着SQL的发展,我只想对此和未来提出改进建议。
反馈
关于没有得到所有范围的问题,我已经修改了查询。请注意内部(选择--范围) AllRanges通过左联接到DataPort表。在本例中,主表现在是AllRanges别名,每个别名都有4行。然后,我对DataPort表进行了左连接。联接基于AllRanges.Required列与条件情况匹配的条件--加上日期的时间条件。
如果您有WHERE子句,它将在内部将左联接转换为内部联接,从而防止所有4个范围。
该走了吧。
发布于 2021-12-15 15:42:33
我不确定你的代码有什么问题.您是说您缺少"91-180“和”271“360?您确定您的子查询中有与此范围相匹配的行吗?
https://stackoverflow.com/questions/70365725
复制相似问题