Вот решение, которое корректно работает с вашими образцами данных. Он генерирует список дат, используя различные значения, которые можно найти в столбце created_date
, а затем LEFT JOIN
сопоставляет его с таблицей. Условия JOIN
несут логику, которую вы описали. Мне кажется, что вам не нужно проверять status
записей, поскольку, по-видимому, любая запись, которая не имеет NULL
completed_date
, находится в статусе Comp
.
SELECT
dt.created_date,
COUNT(t.id)
FROM
(SELECT DISTINCT created_date FROM mytable) dt
LEFT JOIN mytable t
ON t.created_date <= dt.created_date
AND (t.completed_date IS NULL OR t.completed_date > dt.created_date)
GROUP BY dt.created_date
Это Демонстрация на DB Fiddle с вашими примерами возвращает данные:
| created_date | COUNT(t.id) |
| ------------ | ----------- |
| 2019-03-18 | 1 |
| 2019-03-19 | 2 |
| 2019-03-20 | 4 |
| 2019-03-21 | 4 |
| 2019-03-22 | 3 |
Можно также использовать Математику:: Вокруг сделать это:
$ perl -MMath::Round=nearest -e 'print nearest(.001, 0.1), "\n"'
0.1
$ perl -MMath::Round=nearest -e 'print nearest(.001, 0.11111), "\n"'
0.111
Это даст Вам вывод Ваш поиск,
sub dropTraillingZeros{
$_ = shift;
s/(\d*\.\d{3})(.*)/$1/;
s/(\d*\.\d)(00)/$1/;
s/(\d*\.\d{2})(0)/$1/;
print "$_\n";
}
dropTraillingZeros(0);
dropTraillingZeros(0.1);
dropTraillingZeros(0.11);
dropTraillingZeros(0.111);
dropTraillingZeros(0.11111111);
Используйте следующее непосредственно:
my $s = sprintf('%.3f', $f);
$s =~ s/\.?0*$//;
print $s
... или определите подпрограмму, чтобы сделать это более в общем:
sub fstr {
my ($value,$precision) = @_;
$precision ||= 3;
my $s = sprintf("%.${precision}f", $value);
$s =~ s/\.?0*$//;
$s
}
print fstr(0) . "\n";
print fstr(1) . "\n";
print fstr(1.1) . "\n";
print fstr(1.12) . "\n";
print fstr(1.123) . "\n";
print fstr(1.12345) . "\n";
print fstr(1.12345, 2) . "\n";
print fstr(1.12345, 10) . "\n";
Печать:
0
1
1.1
1.12
1.123
1.123
1.12
1.12345