mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-19 16:20:50 +00:00
updates due to review
This commit is contained in:
parent
35f19522e7
commit
a3d8db6e1e
@ -55,28 +55,29 @@ SELECT now() as current_date_time, current_date_time + INTERVAL 4 DAY
|
||||
└─────────────────────┴───────────────────────────────┘
|
||||
```
|
||||
|
||||
也可以同時使用多個間隔:
|
||||
不同类型的间隔不能合并。 你不能使用诸如 `4 DAY 1 HOUR` 的时间间隔. 以小于或等于时间间隔最小单位的单位来指定间隔,例如,时间间隔 `1 day and an hour` 可以表示为 `25 HOUR` 或 `90000 SECOND`.
|
||||
|
||||
你不能对 `Interval` 类型的值执行算术运算,但你可以向 `Date` 或 `DateTime` 数据类型的值添加不同类型的时间间隔,例如:
|
||||
|
||||
``` sql
|
||||
SELECT now() AS current_date_time, current_date_time + (INTERVAL 4 DAY + INTERVAL 3 HOUR)
|
||||
SELECT now() AS current_date_time, current_date_time + INTERVAL 4 DAY + INTERVAL 3 HOUR
|
||||
```
|
||||
|
||||
``` text
|
||||
┌───current_date_time─┬─plus(current_date_time, plus(toIntervalDay(4), toIntervalHour(3)))─┐
|
||||
│ 2024-08-08 18:31:39 │ 2024-08-12 21:31:39 │
|
||||
└─────────────────────┴────────────────────────────────────────────────────────────────────┘
|
||||
┌───current_date_time─┬─plus(plus(now(), toIntervalDay(4)), toIntervalHour(3))─┐
|
||||
│ 2019-10-23 11:16:28 │ 2019-10-27 14:16:28 │
|
||||
└─────────────────────┴────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
並比較不同直數的值:
|
||||
以下查询将导致异常:
|
||||
|
||||
``` sql
|
||||
SELECT toIntervalMicrosecond(3600000000) = toIntervalHour(1);
|
||||
select now() AS current_date_time, current_date_time + (INTERVAL 4 DAY + INTERVAL 3 HOUR)
|
||||
```
|
||||
|
||||
``` text
|
||||
┌─less(toIntervalMicrosecond(179999999), toIntervalMinute(3))─┐
|
||||
│ 1 │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
Received exception from server (version 19.14.1):
|
||||
Code: 43. DB::Exception: Received from localhost:9000. DB::Exception: Wrong argument types for function plus: if one argument is Interval, then another must be Date or DateTime..
|
||||
```
|
||||
|
||||
## 另请参阅 {#see-also}
|
||||
|
@ -230,8 +230,7 @@ void convertUInt64toInt64IfPossible(const DataTypes & types, TypeIndexSet & type
|
||||
|
||||
DataTypePtr findSmallestIntervalSuperType(const DataTypes &types, TypeIndexSet &types_set)
|
||||
{
|
||||
const auto& granularity_map = getGranularityMap();
|
||||
int min_granularity = std::get<0>(granularity_map.at(IntervalKind::Kind::Year));
|
||||
auto min_interval = IntervalKind::Kind::Year;
|
||||
DataTypePtr smallest_type;
|
||||
|
||||
bool is_higher_interval = false; // For Years, Quarters and Months
|
||||
@ -240,18 +239,18 @@ DataTypePtr findSmallestIntervalSuperType(const DataTypes &types, TypeIndexSet &
|
||||
{
|
||||
if (const auto * interval_type = typeid_cast<const DataTypeInterval *>(type.get()))
|
||||
{
|
||||
int current_granularity = std::get<0>(granularity_map.at(interval_type->getKind()));
|
||||
if (current_granularity > 8)
|
||||
auto current_interval = interval_type->getKind().kind;
|
||||
if (current_interval > IntervalKind::Kind::Week)
|
||||
is_higher_interval = true;
|
||||
if (current_granularity < min_granularity)
|
||||
if (current_interval < min_interval)
|
||||
{
|
||||
min_granularity = current_granularity;
|
||||
min_interval = current_interval;
|
||||
smallest_type = type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_higher_interval && min_granularity <= 8)
|
||||
if (is_higher_interval && min_interval <= IntervalKind::Kind::Week)
|
||||
throw Exception(ErrorCodes::NO_COMMON_TYPE, "Cannot compare intervals {} and {} because the amount of days in month is not determined", types[0]->getName(), types[1]->getName());
|
||||
|
||||
if (smallest_type)
|
||||
|
@ -50,24 +50,9 @@ DataTypePtr getLeastSupertypeOrString(const TypeIndexSet & types);
|
||||
|
||||
DataTypePtr tryGetLeastSupertype(const TypeIndexSet & types);
|
||||
|
||||
/// A map that enumerated all interval kinds in ascending order with a conversion value to a next interval
|
||||
inline const std::unordered_map<IntervalKind::Kind, std::pair<int, int>> & getGranularityMap()
|
||||
{
|
||||
static std::unordered_map<IntervalKind::Kind, std::pair<int, int>> granularity_map =
|
||||
{
|
||||
{IntervalKind::Kind::Nanosecond, {1, 1000}},
|
||||
{IntervalKind::Kind::Microsecond, {2, 1000}},
|
||||
{IntervalKind::Kind::Millisecond, {3, 1000}},
|
||||
{IntervalKind::Kind::Second, {4, 60}},
|
||||
{IntervalKind::Kind::Minute, {5, 60}},
|
||||
{IntervalKind::Kind::Hour, {6, 24}},
|
||||
{IntervalKind::Kind::Day, {7, 7}},
|
||||
{IntervalKind::Kind::Week, {8, 4}},
|
||||
{IntervalKind::Kind::Month, {9, 3}},
|
||||
{IntervalKind::Kind::Quarter, {10, 4}},
|
||||
{IntervalKind::Kind::Year, {11, 1}}
|
||||
};
|
||||
return granularity_map;
|
||||
/// A vector that shows the conversion rates to the next Interval type starting from NanoSecond
|
||||
static std::vector<int> interval_conversions = {1000, 1000, 1000, 60, 60, 24, 7, 4, 3, 4, 1};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1582,42 +1582,22 @@ struct ConvertImpl
|
||||
if (from == to || arguments[0].column->empty())
|
||||
return arguments[0].column;
|
||||
|
||||
const auto &map = getGranularityMap();
|
||||
Int64 conversion_factor = 1;
|
||||
Int64 result_value;
|
||||
|
||||
int from_position = map.at(from).first;
|
||||
int to_position = map.at(to).first; // Positions of each interval according to granurality map
|
||||
int from_position = static_cast<int>(from.kind);
|
||||
int to_position = static_cast<int>(to.kind); // Positions of each interval according to granurality map
|
||||
|
||||
if (from_position < to_position)
|
||||
{
|
||||
for (int i = from_position - 1; i <= to_position; ++i)
|
||||
{
|
||||
// Find the kind that matches this position
|
||||
for (const auto &entry : map)
|
||||
{
|
||||
if (entry.second.first == i)
|
||||
{
|
||||
conversion_factor *= entry.second.second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
conversion_factor *= interval_conversions[i];
|
||||
result_value = arguments[0].column->getInt(0) / conversion_factor;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = from_position - 1; i >= to_position; --i)
|
||||
{
|
||||
for (const auto &entry : map)
|
||||
{
|
||||
if (entry.second.first == i)
|
||||
{
|
||||
conversion_factor *= entry.second.second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
conversion_factor *= interval_conversions[i];
|
||||
result_value = arguments[0].column->getInt(0) * conversion_factor;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user