Содержание

Форматы времени в MySQL: TIMESTAMP vs DATE[TIME]

В MySQL 5 есть несколько типов данных для хранения даты и времени. Это TIMESTAMP, DATE, DATETIME, TIME и YEAR. Все они обладают своими особенностями, и выбор в пользу того или иного календарного типа должен производиться отдельно в каждой конкретной ситуации. Я хотел бы поделиться с вами результатом моего сегодняшнего миниисследования этих типов, в том числе в аспекте работы с временными зонами.Итак, все календарные типы данных подробно описаны в разделе «10.3. Date and Time Types» руководства по MySQL. А важная информация, касающаяся поддержки СУБД временных зон, расписана в разделе «9.7. MySQL Server Time Zone Support». Все следующее далее базируется на изучении руководства. В то же время, в здесь указаны лишь нюансы выбора в пользу того или иного типа, поэтому этот материал никак не заменяет мануал, но дополняет его.

Вначале краткая характеристика каждого из типов:

  • TIMESTAMP — тип данных для хранения даты и времени. Данные хранятся в виде количества секунд, прошедших с начала «эпохи Юникса». Диапазон значений: 1970-01-01 00:00:00 — 2038-12-31 00:00:00. Занимает 4 байта.
  • YEAR — тип данных для хранения года. Диапазон значений: 1901 — 2155. Занимает 1 байт.
  • DATE — тип данных для хранения даты. Диапазон значений: 1000-01-01 — 9999-12-31. Занимает 3 байта.
  • TIME — тип данных для хранения времени. Диапазон значений: −828:59:59 — 828:59:59. Занимает 3 байта.
  • DATETIME — тип данных для хранения даты и времени. Диапазон значений: 1000-01-01 00:00:00 — 9999-12-31 00:00:00. Занимает 8 байт.

Хозяйке на заметку. Интересно то, что большинство программистов полагают, что понятие «timestamp» — это и есть Unix-время. На самом же деле, timestamp — это метка, которая представляет собой последовательность символов, обозначающих дату и / или время, когда определенное событие произошло. А «время Юникса» (Unix time) или POSIX time — это количество секунд, прошедших с полуночи 1 января 1970 года по UTC.

Понятие timestamp шире, чем Unix time.

Проанализировав описание типов, представленное выше, можно сделать практически все выводы о достоинствах и недостатках тех или иных типов. Все довольно просто и очевидно.

Но прежде, чем рассказать об использовании этих типов, хочу заметить, что на практике часто используется другой тип для хранения даты и времени: целочисленное значение (для хранения даты — INT (4 байта), даты и времени — BIGINT (8 байт)). Отличие использования целочисленных типов от DATE и DATETIME лишь в том, что при выводе данные не форматируются, а в вычислениях с датами и временем целые числа требуется преобразовывать в соответствующий календарный тип. Кроме того, не производится проверка на валидность представленного значения перед сохранением. Возможности сортировки сохраняются. Поэтому INT и BIGINT имеет смысл использовать в тех же случаях, как DATE и DATETIME, с целью максимизации переносимости и независимости от СУБД. Других преимуществ я не вижу, если они есть, предлагаю указать в комментах.

Начнем с самого простого — тип YEAR. Единственное его достоинство — малый размер — всего-то 1 байт. Но из-за этого действует строгое ограничение по диапазону допустимых значений (тип может хранить только 255 разных значений). Мне сложно представить практическую ситуацию, когда может потребоваться хранить года строго в диапазоне от 1901 до 2155. Кроме того, тип SMALLINT (2 байта) дает диапазон, достаточный в большинстве ситуаций для хранения года. А экономить 1 байт на строке в таблице БД в наше время смысла нет.

Типы DATE и DATETIME

можно объединить в одну группу. Они хранят дату или дату и время с довольно широким диапазоном допустимых значений, независимую от установленной на сервере временной зоны. Их использование определенно имеет практический смысл. Но если требуется хранить даты исторических событий, уходящие в прошлое за Нашу эру, придется выбрать другие типы данных. Для хранения дат неких событий, потенциально выходящих за рамки диапазона типа TIMESTAMP (дни рождений, даты выпуска продуктов, избрания президентов, запуски космических ракет и т. д.), отлично подойдут эти типы. При использовании этих типов нужно учитывать один важный нюанс, но об этом ниже.

Тип TIME

можно использовать для хранения промежутка времени, когда не нужна точность меньше 1 секунды, и промежутки времени меньше 829 часов. Добавить тут больше нечего.

Остался самый интересный тип — TIMESTAMP. Рассматривать его надо в сравнении с DATE и DATETIME: TIMESTAMP тоже предназначен для хранения даты и/или времени происхождения неких событий. Важное отличие между ними в диапазонах значений: очевидно, что TIMESTAMP не годится для хранения исторических событий (даже таких, как дни рождений), но отлично подходит для хранения текущих (логирование, даты размещения статей, добавления товаров, оформления заказов) и предстоящих в обозримом будущем событий (выходы новых версий, календари и планировщики и т.д).

Основное удобство использования типа TIMESTAMP состоит в том, что для столбцов этого типа в таблицах можно задавать значение по умолчанию в виде подстановки текущего времени, а так же установки текущего времени при обновлении записи. Если вам требуется эти возможности, то с вероятностью 99% TIMESTAMP — именно то, что вам нужно. (Как этоделать, смотрите в мануале.)

Не стоит бояться того, что с приближением к 2038 году ваш софт перестанет работать. Во-первых, до этого времени вашим софтом, скорее всего, просто перестанут пользоваться (особенно версиями, которые пишутся сейчас). Во-вторых, с приближением к этой дате разработчики MySQL обязательно что-нибудь придумают для сохранения работоспособности вашего софта. Все решится так же хорошо, как проблема Y2K.

Итак, тип TIMESTAMP используем для хранения дат и времени свершения событий нашего времени, а DATETIME и DATE — для хранения дат и времени свершения исторических событий, или событий глубокого будущего.

Диапазоны значений — это важное отличие между типами TIMESTAMP, DATETIME и DATE, но не главное. Главное то, что TIMESTAMP хранит значение в UTC. При сохранении значения оно переводится из текущего временной зоны в UTC, а при его чтении — во время текущей временной зоны из UTC.

DATETIME и DATE хранят и выводят всегда одно и то же время, независимо от временных зон.

Временные зоны устанавливаются в СУБД MySQL глобально или для текущего подключения.Последнее можно использовать для обеспечения работы разных пользователей в разных временных зонах на уровне СУБД. Все значения времени физически будут храниться в UTC, а приниматься от клиента и отдаваться клинту — в значениях его временной зоны. Но только при использовании типа данных TIMESTAMP. DATE и DATETIME всегда принимают, хранят и отдают одно и то же значение.

Функция NOW() и ее синонимы возвращают значение времени в текущей временной зоне пользователя.

Учитывая все эти обстоятельства, необходимо быть крайне внимательными при изменении временной зоны в пределах подключения к серверу и использовании типов DATE и DATETIME. Если надо хранить дату (например, дату рождения), то никаких проблем не будет. Дата рождения в любой зоне одинаковая. Т.е. если вы родились 1 января в 0:00 UTC/GMT+0, то это не значит, что в Америке будут праздновать ваш день рождения 31 декабря. Но если вы решите хранить время события в столбце DATETIME, то тут уже построить работу с пользовательскими временными зонами на уровне СУБД просто не выйдет. Поясню на примере:

Пользователь X работает в зоне UTC/GMT+2, Y — в зоне UTC/GMT+3. Для соединений пользователей с MySQL установлена соответствующая (у каждого своя) временная зона. Пользователь размещает сообщение на форуме, нас интересует дата написания сообщения.

Вариант 1: DATETIME. Пользователь X пишет сообщение в 14:00 UTC/GMT+2. Значение в поле «дата» сообщения подставляется как результат выполнения функции NOW() — 14:00. Пользователь Y считывает время написания сообщения и видит те же 14:00. Но у него в настройках стоитзона UTC/GMT+3, и он думает, что сообщение было написано не только что, а час назад.

Вариант 2: TIMESTAMP. Пользователь X пишет сообщение в 14:00 UTC/GMT+2. В поле «дата» попадает результат выполнения функции NOW() — в данном случае — 12:00 UTC/GMT+0. ПользовательY считывает время написания сообщения и получает (UTC/GMT+3)(12:00 UTC/GMT+0) = 15:00 UTC/GMT+3.

Все получается ровно так, как мы хотим. И главное — пользоваться этим крайне удобно: для поддержки пользовательских временных зон не нужно писать никакой код приведения времени.

Возможности подстановки текущего времени и работы с временными зонами в типе TIMESTAMP настолько весомы, что если вам в неком логе надо хранить дату без времени, все равно стоит использовать TIMESTAMP, вместо DATE, не экономя 1 байт разницы между ними. При этом на «00:00:00» просто не обращать внимания.

Если же вы не можете использовать TIMESTAMP из-за относительно малого диапазона его значений (а обычно это 1—2 случая против 10—15 в базе сайта), придется использовать DATETIME и аккуратно его корректировать значения в нужных местах (т.е. при записи в это поле переводить дату в UTC, а при чтении — во время в зоне считывающего пользователя). Если вы храните только дату, то скорее всего не важно, какая у вас временная зона: новый год все празднуют 1 января по локальному времени, ничего переводить тут не понадобится.

Как timestamp перевести в дату sql

How to Convert Timestamp to Datetime in MySQL?

In this article, we are going to learn how to convert Timestamp to Datetime in MySQL.To execute these queries, we need to first add integer data(written in timestamp format) and then use the FROM_UNIXTIME() function to convert it into “Datetime” Data Type.

FROM_UNIXTIME():

This function in MySQL returns a Datetime representation of a Unix Timestamp that has been entered as a parameter.

Step 1: We will create a Database

For the creation of a database, we will use the following query

Query:

Step 2: Use the created Database

Now we use a created database with the help of the following query.

Query:

Step 3: Creating a table inside the database

We will create a table with a single column having datatype int for storing the timestamp values. We use the following query to create a table:

Query:

Step 4: Insertion of data into the created table

We will insert data in timestamp format into the table by using the following query:

Query:

Step 5:

Here we need to show data in another format, so we first select it using the “SELECT statement” in MySQL. We will then pass the selected data from the TIMESTAMP_VAL column as a parameter in FROM_UNIXTIME() function. The syntax of the FROM_UNIXTIME() is :

The format is NOT compulsory here. If we do not write the format, the query used will be :

Query I:

If we use the format ‘%Y %D %M %h:%i:%s’ , then the query used will be:

How to convert timestamp / rowversion to a date and time in SQL Server?

How to convert timestamp / rowversion to a date and time in SQL Server?

I have several tables where I would like to track the last update, with column names like ModifiedAt , UpdatedAt , UpdatedDate .

Would this be possible if these were with a Rowversion data type or Timestamp data type?

1 Answer 1

It is not possible to convert the TimeStamp colunm into a Date & Time format. Microsoft has renamed the TimeStamp data type to RowVersion to avoid the confusion.

The timestamp/rowversion data type is really just a Database Transaction ID, and it can also be stored in a column of the Binary(8) data type.

But here is a work-around to implement the ModifiedAt, UpdatedDate column type. This will translate (or «convert») a RowVersion column into a SmallDateTime datatype, that can be formatted according to your needs.

But you need to do a bit of work;

1. Create a table «UpdateTimeStamp» with three columns

(CreatedDate Smalldatetime, NewRowVersion, OldRowVersion) like this:

Insert the first row manually

2. Create a SQL Agent job

Create a standard SQL Agent job which inserts one row in the table every one minute.

Make step 1 run this code:

Set the schedule to run every 1 minute.

3. Query the data

You need to write your query with a join to the UpdateTimeStamp table to your table with a between join clause like this:

Caveat, buts.

1) Microsoft SQL Server is not very good at «date range join» clauses, so if you do not need minute resolution, but 10 minute accuracy is acceptable, then you can improve the query speed a bit with lowering the frequency of the SQL Agent job to 10 minute intervals.

2) This will only work for time periods where the SQL Agent job has been running, as it is not easy to create the dbo.UpdateTimeStamp table retrospectively. Unless you have an old table with a RowVersion/TimeStamp datatype, and this table also never sees updates, and the table has a CreatedDate column. And the table has to be in the same database on the same server.

Bonus features

The RowVersion column was already added to many tables already in our Data Warehouse, because I use it as a watermark for loading data into our Data Marts. So now I have the this feature as a debug option, when I need to investigate when things went wrong in our facts and dimensions. Furthermore I do not need a trigger, which may have performance issues and/or stability issues, if not coded correctly.

Как преобразовать столбец timestamp SQL Server в формат даты и времени

Так как SQL Server возвращает отметку времени, например ‘Nov 14 2011 03:12:12:947PM’ , есть ли простой способ преобразования формата строки в дату, например «Y-m-d H: i: s».

До сих пор я использую

ОТВЕТЫ

Ответ 1

Тип данных SQL Server TIMESTAMP не имеет никакого отношения к дате и времени!

Это просто шестнадцатеричное представление последовательного 8-байтового целого числа — это полезно только для того, чтобы убедиться, что строка не изменилась с момента ее чтения.

Вы можете прочитать шестнадцатеричное целое число или, если хотите, BIGINT . Как пример:

В более новых версиях SQL Server он называется RowVersion — поскольку это действительно так. См. документы MSDN по ROWVERSION:

Тип данных, который предоставляет автоматически генерируемые уникальные двоичные числа в базе данных. rowversion обычно используется в качестве механизма для версионно-штамповочных строк таблицы. тип данных rowversion просто инкрементный и не сохранить дату или время. Для записи даты или времени используйте datetime2 тип данных.

Таким образом, вы не можете преобразовать SQL Server TIMESTAMP в дату/время — это просто не дата/время.

Но если вы говорите о метке времени, но на самом деле вы имеете в виду столбец DATETIME — тогда вы можете использовать любой из этих допустимых форматов даты, описанных в разделе CAST и CONVERT справки MSDN. Они определены и поддерживаются «из коробки» SQL Server. Все остальное не поддерживается, например Вы должны выполнять много ручной и конкатенации (не рекомендуется).

Формат, который вы ищете, выглядит как канонический ODBC (style = 121):

Ответ 2

Используя приведение, вы можете получить дату из поля отметки времени:

Ответ 3

Мои коллеги помогли мне в этом:

Ответ 4

Работает нормально, кроме этого сообщения:

Неявное преобразование из типа данных varchar в метку времени не допускается. Используйте функцию CONVERT для выполнения этого запроса

Так что да, TIMESTAMP ( RowVersion ) не НЕ ДАТА 🙂

Если честно, я довольно долго возился, чтобы найти способ преобразовать его в дату.

Лучший способ — преобразовать его в INT и сравнить. Это то, для чего предназначен этот тип.

Если ты хочешь свидание — просто добавь колонку Datetime и живи долго и счастливо 🙂

Ответ 5

«Вы продолжаете использовать это слово. Я не думаю, что это означает, что вы думаете, что это значит». — Иниго Монтойя

Отметка времени не имеет абсолютно никакого отношения ко времени, как первоначально сказал marc_s.

Обратите внимание на вывод, что Ts (hex) увеличивается на единицу для каждой записи, но фактическое время имеет разрыв в 10 секунд. Если бы это было связано со временем, тогда бы была временная метка, чтобы соответствовать разнице во времени.

Ответ 6

Самый простой способ сделать это:

Это дает столбец даты по крайней мере в читаемом формате. Далее, если вы хотите изменить формат te, нажмите здесь.

Ответ 7

После имплементации преобразования в целое число CONVERT (BIGINT, [timestamp]) как timestamp У меня есть результат, как

446701117 446701118 446701119 446701120 446701121 446701122 446701123 446701124 446701125 446701126

Да, это не дата и время, это серийные номера

Ответ 8

Почему бы не попробовать FROM_UNIXTIME(unix_timestamp, format) ?

Ответ 9

Некоторые из них действительно преобразуются в дату и время начиная с SQL Server 2008 и далее.

Попробуйте следующий SQL-запрос, и вы сами увидите:

Приведенное выше приведёт к 2009-12-30 09:51:03:000 , но я встречал те, которые на самом деле не отображаются на дату-время.

Ответ 10

Не уверен, что здесь что-то не хватает, но вы не можете просто преобразовать временную метку следующим образом:

SPBDEV Blog — Сравнение возможностей SQL Server: десятичный и числовой тип, Timestamp и Rowversion, уникальный индекс и уникальное ограничение

Tags: SQL Server, SQL

Thursday, August 15, 2019 1:37:00 PM

Проблема

В SQL Server есть некоторые понятия, которые имеют разные имена, но функционально они эквивалентны. 38-1. Только их имена разные и не более того. Таким образом, эти типы могут использоваться взаимозаменяемо. В следующем примере показано объявление и использование переменных десятичного и числового типов:

DECLARE @numVar NUMERIC (4,2)=16.25

DECLARE @decVar NUMERIC (4,2)=15

SELECT @numVar AS NumericVar, @decVar AS DecimalVar

SET @numVar=@decVar

SELECT @numVar AS NumericVar, @decVar AS DecimalVar

 

Поскольку они относятся к одним и тем же типам, проблем при назначении десятичных и числовых переменных (с одинаковым масштабом и точностью) не возникало. В следующем примере мы можем видеть, что если мы присваиваем значение с более высокой шкалой, оно округляется:

DECLARE @numVar NUMERIC (4,2)=35.98645

DECLARE @decVar NUMERIC (4,2)=35.98645

SELECT @numVar AS NumericVar, @decVar AS DecimalVar

 

Однако, если точность выше, будет сгенерирована ошибка:

DECLARE @numVar NUMERIC (4,2)=355. 98645

DECLARE @decVar NUMERIC (4,2)=335.98645

SELECT @numVar AS NumericVar, @decVar AS DecimalVar

 

Подводя итог, можно сказать, что десятичные и числовые типы данных идентичны, и разработчики могут свободно пользоваться тем, что они предпочитают.

Каковы различия между типами данных Timestamp и Rowversion SQL Server?

На самом деле, эти типы данных являются синонимами. Объекты этих типов данных содержат автоматически сгенерированные двоичные числа, которые являются уникальными в базе данных. Размер хранилища для этих типов данных составляет 8 байт. В то время как обнуляемый столбец типа данных rowversion (timestamp) семантически эквивалентен столбцу varbinary (8), ненулевой столбец типа rowversion (timestamp) семантически эквивалентен двоичному столбцу (8).

Несмотря на свое название, тип данных timestamp (rowversion) не имеет ничего общего с типами данных date и time. Тип данных Rowversion (timestamp) представляет собой инкрементное число. Каждый раз, когда строка в таблице, содержащей столбец версии строки (отметка времени), вставляется или обновляется, увеличенное значение версии строки базы данных (отметка времени) вставляется в столбец этой строки. Это делает столбец rowversion (timestamp) очень полезным для обнаружения, сравнения и синхронизации изменений данных в таблицах. В каждой таблице может быть не более одного столбца с типом данных rowversion (timestamp).

Чтобы проиллюстрировать эти типы данных на практике, давайте создадим следующие таблицы с типами данных rowversion и timestamp:

CREATE TABLE ##tmpTableA

(

 Val INT,

 LastChange ROWVERSION NOT NULL

)

CREATE TABLE ##tmpTableB

(

 Val INT,

 LastChange TIMESTAMP NOT NULL

)

INSERT INTO ##tmpTableA(Val) VALUES(1),(2)

INSERT INTO ##tmpTableB(Val) VALUES(3),(4)

SELECT * FROM ##tmpTableA

SELECT * FROM ##tmpTableB


Как видно из обеих таблиц, значения для столбца LastChange были сгенерированы автоматически:

 

Теперь давайте скопируем эти данные в таблицы, в которых есть столбцы с двоичным (8) типом данных для хранения данных версии строк (timestamp) из таблиц выше:

CREATE TABLE ##tmpTableC

(

 Val INT,

 LastChange BINARY(8) NOT NULL

)

CREATE TABLE ##tmpTableD

(

 Val INT,

 LastChange BINARY(8) NOT NULL

)

INSERT INTO ##tmpTableC (Val, LastChange)

SELECT Val, LastChange

FROM ##tmpTableA

INSERT INTO ##tmpTableD (Val, LastChange)

SELECT Val, LastChange

FROM ##tmpTableB

SELECT *

FROM ##tmpTableC

SELECT *

FROM ##tmpTableD

Результат показывает, что данные версии строки (timestamp) успешно копируются в двоичные (8) столбцы, поскольку они семантически эквивалентны:

 

При этом необходимо учитывать некоторые моменты при работе с этими типами данных:

  • Согласно Microsoft, тип данных timestamp устарел и будет удален в будущих версиях. Таким образом, рекомендуется заменить timestamp везде, где это возможно.
  • В случае создания таблицы в SQL Server Management Studio и установки типа столбца единственным доступным вариантом является timestamp. В выпадающем списке нет доступных версий строк. Даже если таблица создана с использованием кода T-SQL, а тип столбца определен как преобразование строк, в Management Studio его тип будет отображаться как timestamp.
  • В коде T-SQL можно создать столбец с типом timestamp, не упоминая имя столбца. В этом случае автоматически будет сгенерировано имя столбца, который будет называться TIMESTAMP. Это невозможно, если в коде T-SQL столбец определен как версия строки вместо timestamp.

Есть ли различия между уникальным индексом SQL Server и уникальным ограничением?

Оба могут быть использованы для обеспечения уникальности значений в столбце (столбцах). Создание обоих означает, что SQL Server по умолчанию создает некластеризованный уникальный индекс для этих столбцов. Если в таблице нет кластеризованного индекса, можно создать уникальный индекс, а также уникальное ограничение как кластеризованное. С точки зрения производительности, механизм SQL Server не учитывает, создается ли уникальный индекс как уникальное ограничение или индекс при выборе плана выполнения, и, следовательно, нет разницы в производительности.

Теперь давайте создадим таблицу, а затем уникальный индекс и уникальное ограничение для ее столбцов:

CREATE TABLE ##TestTable

(

 ID INT IDENTITY(1,1),

 Val1 INT,

 Val2 INT

)

— Unique index

CREATE UNIQUE INDEX UIX_TestTable_Val2 ON ##TestTable(Val1)

—Unique constraint

ALTER TABLE ##TestTable

ADD CONSTRAINT UC_TestTable_Val2

UNIQUE (Val2)

SELECT * FROM tempdb.sys.indexes WHERE OBJECT_ID = object_id(‘tempdb..##TestTable’)


Из последнего запроса мы видим, что независимо от создания уникального ограничения (unique constraint) или уникального индекса (unique index), уникальные некластеризованные индексы были созданы в обоих столбцах. Однако для столбца Val2 ясно показано, что это уникальное ограничение, где is_unique_constraint = 1

 

Тем не менее, важно упомянуть некоторые технические отличия:

  • В отличие от создания уникального индекса, в случае создания уникального ограничения настройка некоторых параметров индекса недоступна как в SSMS, так и в коде T-SQL.
  • Невозможно удалить индекс, созданный в результате создания уникального ограничения, с помощью команды DROP INDEX. Вместо этого следует использовать команду DROP CONSTRAINT, которая, в свою очередь, также удаляет связанный индекс.

В целом, для обеспечения уникальности значений в столбце, создания уникальных индексов вместо уникальных ограничений, в некоторых условиях можно рассматривать как более гибкое решение. Это связано с тем, что разработчики имеют больше возможностей при создании индексов с использованием кода T-SQL, а также, в отличие от уникальных ограничений, нет особых предварительных условий для удаления уникальных индексов. Кроме того, нет никаких различий в производительности. Уникальные ограничения могут рассматриваться как способ прояснения значения и цели индекса.

В чем разница между операторами <> и! = (Не равно) SQL Server?

Это одни и те же операторы, и нет различий с точки зрения функциональности или производительности. Оба сравнивают два выражения, и результат будет TRUE, если они не равны. Если они равны, результат будет FALSE. Предполагается, что оба операнда не равны NULL. Вы можете использовать SET ANSI_NULLS, чтобы определить желаемый результат сравнения с NULL.

  • Единственное, что стоит упомянуть, это то, что оператор <> является стандартом ISO, а оператор ! = — нет. Во всяком случае, это не имеет никакого значения в их функциональности.

В следующем примере показано простое использование этих операторов:

DECLARE @value INT=5

—Using <>

IF(@value <> 0)

   SELECT 20/@value

ELSE

   SELECT 0

—Using !=

IF(@value != 0)

   SELECT 20/@value

ELSE

   SELECT 0

 

В обоих случаях результат равен «4», потому что @value равен не «0», а «5»:

 

Напротив, в следующем примере мы получим 0 для обоих случаев. Это потому, что 0 = 0 и, следовательно, 0 <> 0 (0! = 0) возвращает FALSE:

 

DECLARE @value INT=0

—Using <>

IF(@value <> 0)

   SELECT 20/@value

ELSE

   SELECT 0

—Using !=

IF(@value != 0)

   SELECT 20/@value

ELSE

   SELECT 0

 

Есть ли разница между INNER JOIN и JOIN в SQL Server?

Они абсолютно эквивалентны. JOIN возвращает все строки из двух или более таблиц, где выполняется условие соединения. Он может быть написан со словом INNER и без него и зависит только от предпочтений разработчика:

 

Аналогично, OUTER может быть пропущен в соединениях LEFT OUTER, RIGHT OUTER и FULL OUTER:

 

Хотя некоторые разработчики чувствуют себя более комфортно, используя ключевое слово OUTER, утверждая, что это делает код более читабельным, другие, которые не разделяют это представление, всегда пропускают это ключевое слово. В любом случае, ключевое слово OUTER ничего не меняет в результате, поэтому разработчики могут использовать свой предпочтительный стиль.

Заключение

В заключение, это некоторые понятия в SQL Server, которые функционально эквивалентны. Различия между некоторыми из вышеописанных концепций заключаются только в их именах или синтаксисе (таких как десятичные и числовые типы данных, операторы “! =” и “<>”, ключевое слово OUTER в соединениях и т. д.). Существуют и другие концепции, которые функционально эквивалентны, но все же имеют некоторые незначительные различия, связанные с их использованием (например, ограничения UNIQUE INDEX и UNIQUE, а также типы данных timestamp и rowversion).

Документация JDK 19 — Главная

  1. Главная
  2. Ява
  3. Java SE
  4. 19

Обзор

  • Прочтите меня
  • Примечания к выпуску
  • Что нового
  • Руководство по миграции
  • Загрузить JDK
  • Руководство по установке
  • Формат строки версии

Инструменты

  • Технические характеристики инструментов JDK
  • Руководство пользователя JShell
  • Руководство по JavaDoc
  • Руководство пользователя средства упаковки

Язык и библиотеки

  • Обновления языка
  • Основные библиотеки
  • HTTP-клиент JDK
  • Учебники по Java
  • Модульный JDK
  • Руководство программиста API бортового регистратора
  • Руководство по интернационализации

Технические характеристики

  • Документация API
  • Язык и ВМ
  • Имена стандартных алгоритмов безопасности Java
  • банок
  • Собственный интерфейс Java (JNI)
  • Инструментальный интерфейс JVM (JVM TI)
  • Сериализация
  • Проводной протокол отладки Java (JDWP)
  • Спецификация комментариев к документации для стандартного доклета
  • Прочие характеристики

Безопасность

  • Руководство по безопасному кодированию
  • Руководство по безопасности

Виртуальная машина HotSpot

  • Руководство по виртуальной машине Java
  • Настройка сборки мусора

Управление и устранение неполадок

  • Руководство по устранению неполадок
  • Руководство по мониторингу и управлению
  • Руководство по JMX

Client Technologies

  • Руководство по специальным возможностям Java

DATE_TRUNC: Объяснение функции временной метки SQL

В мире постоянно расширяющихся потоков данных мы полагаемся на временные метки для организации данных с точностью до миллисекунды.

Что такое отметка времени?

Метка времени — это цифровая запись того, когда произошло событие. Временные метки — это типы данных, которые содержат части времени и данных. Они содержат массу информации: год, месяц, день, час, минута, секунда, миллисекунда и зулу .

Они выглядят примерно так:

Довольно некрасиво, правда?

Такой уровень детализации может отвлекать.

Предположим, вы хотите изучить тенденции регистрации пользователей. Вам потребуется агрегировать данные о событиях регистрации по времени возникновения каждого события. Временные метки событий могут помочь, но вам, вероятно, не нужна вся информация, которую они содержат. Возможно, вас интересуют регистрации по годам, месяцам или дням, но подписки по часам, минутам или миллисекундам были бы излишними.

Вот где функция DATE_TRUNC() пригодится. Вы можете использовать его для округления метки времени до нужного вам интервала.

  • Что такое DATE_TRUNC()?

  • Как использовать DATE_TRUNC() в SQL

  • Как создать временной ряд с усеченными временными метками

  • Рекомендуемые статьи

9012

DATE_TRUNC()  – это функция, используемая для округления или усечения метки времени до нужного вам интервала. При использовании для агрегирования данных он позволяет находить временные тенденции, такие как ежедневные покупки или количество сообщений в секунду.

Как использовать DATE_TRUNC() в SQL

Чтобы удалить ненужные детали метки времени, передайте ее функции DATE_TRUNC() . Функция date_trunc сокращает метки времени, чтобы их было легче читать.

Синтаксис:

DATE_TRUNC(‘[interval]’, time_column)

time_column  – это столбец базы данных, который содержит отметку времени, которую вы хотите округлить, а [интервал]  определяет желаемый уровень точности. Вы можете округлить метку времени до одной из следующих единиц времени:

  • microsecond

  • millisecond

  • second

  • minute

  • hour

  • day

  • week

  • month

  • quarter

  • year

  • десятилетие

  • век

  • тысячелетие

Если указанную выше временную метку округлить до 'день' , результат:

2015-10-06T00:00:00. 000Z

Если округлить до 'минута' , это будет выглядеть так: 905-10

88 -06T11:54:00.000Z

Аналогично, 'секунда'  округляется до ближайшей секунды, 'час'  – до ближайшего часа и так далее. 'неделя'  округляется до даты этого понедельника.

Навигация на неспокойном рынке с помощью данных

Послушайте истории руководителей компаний Patreon, Lyft и Greenhouse о том, как они помогали своим бизнес-командам принимать решения на основе данных в первые дни пандемии.

Как создать временной ряд с усеченными временными метками

DATE_TRUNC() особенно полезен, когда вы хотите агрегировать информацию за интервал времени. Используя один из фиктивных наборов данных от Mode’s SQL School, давайте в качестве примера рассмотрим связанные со временем тенденции в регистрации пользователей.

Давайте начнем с этого запроса:

 SELECT произошел_в,
       ID пользователя
  ОТ benn. fake_fact_events
 ГДЕ event_name = 'complete_signup'
   И произошло_в >= '2014-03-10'
   И произошло_в <= '2014-05-26'
 ЗАКАЗАТЬ ПО 1 DESC 

В результате получается таблица, в которой показано время и идентификаторы пользователей, завершивших регистрацию в период с 01.03.14 по 26.05.14:

Просмотр в режиме

не объединяются полезным образом с данными в часах, минутах и ​​миллисекундах. Вот как выглядит запрос, когда вы пытаетесь сгруппировать регистрации по отметке времени:

 SELECT произошел_в,
       COUNT(идентификатор_пользователя)
  ОТ benn.fake_fact_events
 ГДЕ event_name = 'complete_signup'
   И произошло_в >= '2014-03-10'
   И произошло_в <= '2014-05-26'
 СГРУППИРОВАТЬ ПО 1
 ЗАКАЗАТЬ ПО 1 DESC 

И результаты:

Не сильно отличается, верно? Это по-прежнему бесполезно, потому что не позволяет нам группироваться удобным способом. Эти временные метки по-прежнему содержат слишком много информации, чтобы пролить свет на какие-либо значимые тенденции. Давайте вместо этого свернем произошедших_в событий к дню они произошли:

DATE_TRUNC('день', произошло_в)

Вот полный запрос:

 SELECT DATE_TRUNC('день', произошло_в) КАК день, произошло_в
       ID пользователя
  ОТ benn.fake_fact_events
 ГДЕ event_name = 'complete_signup'
   И произошло_в >= '2014-03-10'
   И произошло_в <= '2014-05-26'
 ЗАКАЗАТЬ ПО 1 DESC 

И результаты:

Просмотр в режиме

После усечения временных меток можно получить значения по временному интервалу интервал. Например, вы можете подсчитать количество регистраций, которые произошли за каждый день. Вот запрос:

 SELECT DATE_TRUNC('день', произошло_в) КАК день,
       COUNT(идентификатор_пользователя)
  ОТ benn.fake_fact_events
 ГДЕ event_name = 'complete_signup'
   И произошло_в >= '2014-03-10'
   И произошло_в <= '2014-05-26'
 СГРУППИРОВАТЬ ПО 1
 ЗАКАЗАТЬ ПО 1 DESC 

Вот что вы получите:

Затем эти результаты можно визуализировать в виде ежедневных временных рядов:

Просмотр в режиме

Быстро становится ясно, что количество регистраций падает каждые выходные. Несмотря на то, что это подчеркивает недельный цикл, по-прежнему сложно определить модель недели за неделей. Увеличилось ли количество регистраций за последние несколько месяцев? Были ли заметные провалы?

Чтобы получить это, мы просто переключаем уровень агрегации с «день» на 'неделя' :

 ВЫБЕРИТЕ DATE_TRUNC('неделя', произошло_в) КАК неделя,
       COUNT(идентификатор_пользователя)
  ОТ benn.fake_fact_events
 ГДЕ event_name = 'complete_signup'
   И произошло_в >= '2014-03-10'
   И произошло_в <= '2014-05-26'
 СГРУППИРОВАТЬ ПО 1
 ORDER BY 1 DESC 

Теперь мы можем визуализировать данные в виде недельного временного ряда:

Просмотр в режиме

После удаления шума внутринедельных небольшое падение в конце марта, которое с тех пор восстановилось.

Как видите, функция  DATE_TRUNC()  может быть чрезвычайно полезной для агрегирования данных на основе времени. Примените его к своим данным в Mode Studio, нашей бесплатной версии.

Рекомендуемые статьи

  • Postgresql Date Functions (и 7 способов их использования в бизнес -анализе)

  • AHA Facebook - это проще, чем вы думаете

  • . Общие сведения о временной метке данных SQL

    Поиск и понимание временной метки данных SQL

    книга

    Код статьи: 54497

    calendar_today

    Дата обновления:

    Продукты

    IDMS ИДМС — База данных IDMS - ADS

    Выпуск/Введение

    Описание:

    Работа с базами данных SQL означает, что метки времени будут использоваться во время выполнения для проверки того, что определение таблицы, на которое ссылаются, является правильным для данных, к которым осуществляется доступ. Для выполнения этой проверки метки времени хранятся как в каталоге, так и в физической области данных, где хранятся строки области таблицы SQL. Эти метки времени синхронизируются при создании определения таблицы. Если либо сегмент каталога, либо область данных восстанавливаются без другого, то они могут больше не совпадать, и может возникнуть ошибка проверки метки времени. В такие моменты необходимо увидеть, каковы существующие метки времени, чтобы их можно было повторно синхронизировать.

     

    Разрешение

    Решение:

    Временные метки записываются в каждую физическую область, содержащую таблицы SQL; одна временная метка сохраняется для каждой области. и по одному для каждой таблицы, данные которой хранятся в этой области. Они также записываются в область каталога DDLCAT как часть определения таблицы, в столбец TIMESTAMP таблицы SYSTEM.TABLE в строке, соответствующей рассматриваемой таблице. Во время выполнения эти значения для каждой доступной таблицы должны совпадать друг с другом, в противном случае возникает ошибка. Если область данных и область каталога не синхронизированы, возникнет ошибка, указывающая на проблему с отметкой времени. По этой или другим причинам вам может потребоваться исследовать проблему с отметкой времени в области данных. Начиная с версии 16.0, вы можете сделать это, запустив новую утилиту SYNCHRONIZE STAMPS, которая позволяет сравнивать штампы в области данных и каталоге и, при необходимости, обновлять один штамп другим. Также в версии r16 появилась новая опция для утилиты УСТАНОВИТЬ ШТАМПЫ, которая позволяет заменить существующие штампы синхронизации в области значениями из каталога.

    Как отмечалось выше, в области данных существует два типа временных меток: метки области и метки таблицы. Штампы области называются записями K0 и физически представлены идентификатором записи SR5. Штампы таблицы называются записями K2 и физически представлены идентификатором записи SR9. Они связаны пользовательской структурой индекса, в которой K0 является владельцем, а K являются членами. Если область определена как отметка по области, то временная метка K0 отражает временную метку самой последней обновленной таблицы K2 в этой области. Если область отмечена таблицей, то временная метка K0 всегда будет нулевой.

    В версии R15.0 и более поздних версиях в случае повреждения данных или по другим причинам вы можете просмотреть метки времени, которые хранятся в физической области для таблицы, выполнив следующие действия:

    1. Записи меток времени и пользовательский индекс, соединяющий их, хранится на второй странице области, где хранятся строки для этой таблицы.
    2. Чтобы найти правильную метку времени, вам нужно знать идентификатор таблицы для рассматриваемой таблицы. Вы можете найти эту и другую соответствующую информацию, введя SELECT NAME, TABLEID, SEGMENT, AREA, TIMESTAMP, HEX(TIMESTAMP) FROM SYSTEM.TABLE WHERE NAME =; Если имя таблицы не уникально в этом каталоге, вам также потребуется указать AND SCHEMA = <имя-схемы>' . Мы отображаем как столбец временной метки, так и шестнадцатеричное значение для временной метки, потому что все временные метки хранятся в типе данных SQL TIMESTAMP, что означает, что значения будут храниться в шестнадцатеричном формате и автоматически отображаться в формате EDCBIC при их извлечении. Шестнадцатеричное значение потребуется для сравнения с отметкой времени, хранящейся на странице; читаемый формат позволяет нам увидеть, что означает это значение. Результаты запроса выглядят следующим образом:

     

     3.  Используя сегмент и имя в этом выводе, введите DCMT DIS AREA, чтобы просмотреть диапазон страниц из этой области. В этом примере мы получаем:

     

     

    4. Запустите ПЕЧАТЬ СТРАНИЦЫ второй страницы области. Используйте оставшиеся шаги, чтобы прочитать этот вывод. В нашем примере часть выходных данных, показывающая записи на странице, выглядит следующим образом:

      

       

     СР9(K2) и SR8s. SR5 (K0) — это метка времени для области, записи SR9 (K2) — это метки времени для каждой таблицы, а SR8 — это пользовательская структура индекса, соединяющая их.

      6. Чтобы найти правильную метку времени для рассматриваемой таблицы, вам нужно найти правильный SR9. Вы можете сделать это, просмотрев структуру индекса SR8, если вам это удобно, или просто просмотрев SR9 на странице. Следующие два шага описывают, как просматривать SR9.

      7. Структура для SR5 и SR9записи задокументированы в руководстве CA IDMS DSECT под номером DSECT #D2S2DS. Каждый SR9 начинается с DBKey, который пока можно игнорировать. По смещению x'4' в SR9 находится шестнадцатеричный идентификатор таблицы, связанной с этим SR9. Отметка времени находится со смещением x'8' в каждой записи K2.

      8. Возьмите идентификатор таблицы для рассматриваемой таблицы и преобразуйте его в шестнадцатеричный формат. (1024 будет x'400', 1028 будет x'404' и т. д.) Используйте вывод PRINT PAGE, чтобы найти начальный адрес каждого SR9 и отсканировать каждый для соответствующего идентификатора таблицы по смещению x'4'. В нашем примере из шага № 2 выше мы видим, что идентификатор таблицы равен 1026; преобразование этого в шестнадцатеричный дает x'402'. Если мы просмотрим вывод из вышеприведенного запуска печати страницы, это окажется SR9.начиная со смещения x'0068' на странице. Вы можете увидеть детали этой записи в следующем выводе.

     

      9. #D2S2DS DSECT документирует, что отметка времени в SR9 для рассматриваемой таблицы будет следовать за идентификатором таблицы в следующих двух словах по смещению x'08' в макете записи. В приведенном выше примере мы видим, что значение метки времени здесь равно x'0164BF6886967CC7'. Из вывода на шаге № 2 выше мы видим, что это соответствует значению в каталоге, поэтому для этой таблицы мы не ожидаем ошибок временных меток во время выполнения при сравнении этих значений.

      10. Для версии r16 и выше этот процесс упрощается путем запуска утилиты SYNCHRONIZE STAMPS для этой области с параметром COMPARE. В нашем примере этот вывод выглядит следующим образом:

     

     

    Помните, что поддерживать синхронизацию меток времени намного проще, чем пытаться исправить проблему, когда они не синхронизированы. Если вы выполняете резервное копирование и восстановление областей каталога и связанных областей данных как одной логической единицы, они всегда должны совпадать.