Microsoft SQL Server 쿼리 편집기

Microsoft SQL Server 쿼리 편집기 (Query editor)

MSSQL 쿼리 편집기는 Grafana에서 직접 Transact-SQL 쿼리를 작성할 수 있게 해주며, 시계열과 테이블 시각화용 매크로와 서식 옵션이 내장되어 있어요. Explore나 편집 모드의 대시보드 패널에서 열 수 있어요. 모든 데이터 소스에 공통된 쿼리 개념은 Query and transform data를 참고하세요.

출처: Microsoft SQL Server query editor

본문

Transact-SQL 문법은 Microsoft 문서의 Write Transact-SQL statementsTransact-SQL reference를 참고하세요.

Microsoft SQL Server 쿼리 편집기에는 두 가지 모드가 있어요.

  • Builder 모드
  • Code 모드

편집기 모드를 전환하려면 오른쪽 위의 BuilderCode 탭을 선택해요.

경고: Code 모드에서 Builder 모드로 전환할 때 SQL 쿼리에 대한 변경 사항은 저장되지 않고 빌더 인터페이스에 표시되지 않아요. 코드를 클립보드에 복사하거나 변경을 버릴 수 있어요.

쿼리를 실행하려면 편집기 오른쪽 위의 Run query를 선택해요. 쿼리 작성 외에도 쿼리 편집기에서 매크로와 저장 프로시저를 만들고 사용할 수 있어요.

Builder 모드

Builder 모드는 시각적 인터페이스로 쿼리를 구성할 수 있게 해줘요. 안내된 쿼리 경험을 선호하거나 SQL을 시작하는 사용자에게 좋아요.

다음 구성 요소가 T-SQL 쿼리를 만드는 데 도움을 줘요.

  • Format - MSSQL 쿼리의 드롭다운에서 형식 응답을 선택해요. 기본값은 Table. 자세한 내용과 예시는 Table queries와 Time series queries 참고. Time series 형식 옵션을 선택하면 time 열을 포함해야 해요.
  • Dataset - 드롭다운에서 질의할 데이터베이스를 선택해요. Grafana는 사용자가 접근할 수 있는 모든 데이터베이스로 드롭다운을 자동 채워요. 데이터 소스 구성 페이지나 프로비저닝 파일의 Database 필드에 데이터베이스가 설정되면 사용자는 그 데이터베이스만 질의할 수 있어요.

tempdb, model, msdb, master 시스템 데이터베이스는 쿼리 편집기 드롭다운에 포함되지 않아요.

  • Table - 드롭다운에서 테이블을 선택해요. 데이터베이스 선택 후 다음 드롭다운에 그 데이터베이스의 모든 사용 가능한 테이블이 표시돼요.
  • Data operations - 선택. 드롭다운에서 집계 또는 매크로를 선택해요. + 기호를 클릭해 데이터 연산을 여러 개 추가할 수 있어요. 데이터 연산을 제거하려면 휴지통 아이콘을 클릭해요.
    • Column - 집계를 실행할 열을 선택해요.
    • Interval - 드롭다운에서 간격을 선택해요. 드롭다운에서 time group 매크로를 선택하면 이 옵션을 볼 수 있어요.
    • Fill - 선택. 해당 간격에 데이터가 없을 때 누락된 시간 간격을 기본값(예: NULL, 0 또는 지정 값)으로 채우는 FILL 메서드를 추가해요. 이는 시계열의 연속성을 보장해 시각화에서 공백을 피해요.
    • Alias - 선택. 드롭다운에서 별칭을 추가해요. 상자에 직접 입력하고 Enter를 눌러 자체 별칭을 추가할 수도 있어요. 별칭을 제거하려면 X를 클릭해요.
  • Filter - 필터를 추가하려면 토글.
    • Filter by column value - 선택. Filter를 토글하면 드롭다운에서 필터할 열을 추가할 수 있어요. 추가 열로 필터링하려면 조건 드롭다운 오른쪽의 + 기호를 클릭해요. 조건 옆의 드롭다운에서 다양한 연산자를 선택할 수 있어요. 여러 필터를 추가하면 AND 또는 OR 연산자로 조건이 평가되는 방식을 정의해요. AND는 모든 조건이 참이어야 하고, OR는 어느 조건이든 참이면 돼요. 두 번째 드롭다운으로 필터 값을 선택해요. 필터를 제거하려면 옆의 X 아이콘을 클릭해요. date-type 열을 선택하면 연산자 목록에서 매크로를 사용하고 timeFilter를 선택해 선택한 날짜 열과 함께 $__timeFilter 매크로를 쿼리에 삽입할 수 있어요.
  • Group - GROUP BY 열을 추가하려면 토글.
    • Group by column - 드롭다운에서 필터할 열을 선택해요. + 기호를 클릭해 여러 열로 필터링해요. 필터를 제거하려면 X를 클릭해요.
  • Order - ORDER BY 문을 추가하려면 토글.
    • Order by - 드롭다운에서 정렬할 열을 선택해요. 오름차순(ASC) 또는 내림차순(DESC)을 선택해요.
    • Limit - 검색 결과 수에 선택적 제한을 추가할 수 있어요. 기본값은 50.
  • Preview - 쿼리 빌더가 생성한 SQL 쿼리 미리보기 토글. 기본적으로 켜져 있어요.

형식 사용에 대한 자세한 내용은 Table queries와 Time series queries 참고.

Code 모드

Code 모드는 자동 완성과 문법 강조 같은 유용한 기능이 있는 텍스트 편집기로 복잡한 쿼리를 만들 수 있게 해줘요. SQL 쿼리를 완전히 제어해야 하거나 시각적 쿼리 모드에서 사용할 수 없는 기능을 원하는 고급 사용자에게 이상적이에요. 서브쿼리 작성, 매크로 사용, 고급 필터링·서식 적용에 특히 유용해요. 시각적 모드로 다시 전환할 수 있지만 일부 커스텀 쿼리는 완전히 호환되지 않을 수 있어요.

Code 모드 툴바 기능

Code 모드에는 편집기 오른쪽 아래에 있는 툴바에 몇 가지 기능이 있어요.

  • 쿼리를 다시 서식화하려면 중괄호 버튼({})을 클릭해요.
  • 코드 편집기를 펼치려면 아래쪽을 가리키는 셰브론 버튼을 클릭해요.
  • 쿼리를 실행하려면 Run query 버튼을 클릭하거나 키보드 단축키 Ctrl/Cmd + Enter/Return을 사용해요.

자동 완성 사용

Code 모드의 자동 완성은 입력하는 동안 자동으로 작동해요. 수동으로 자동 완성을 트리거하려면 키보드 단축키 Ctrl/Cmd + Space를 사용해요. Code 모드는 테이블, 열, SQL 키워드, 표준 SQL 함수, Grafana 템플릿 변수, Grafana 매크로의 자동 완성을 지원해요.

참고: 테이블을 지정하기 전에는 열을 자동 완성할 수 없어요.

매크로

문법을 단순화하고 날짜 범위 필터 같은 동적 구성 요소를 허용하기 위해 쿼리에 매크로를 추가할 수 있어요. SELECT 절에서 매크로를 사용해 시계열 쿼리 생성을 단순화해요. Data operations 드롭다운에서 $__timeGroup이나 $__timeGroupAlias 같은 매크로를 선택해요. 그다음 Column 드롭다운에서 시간 열을, Interval 드롭다운에서 시간 간격을 선택해요. 이는 선택한 시간 그룹화에 기반한 시계열 쿼리를 생성해요.

경고: 시간 매크로($__time, $__timeFilter 등)는 Microsoft SQL Server에서 시간대 매개변수를 지원하지 않으며 항상 UTC 값으로 확장돼요. 타임스탬프가 UTC로 저장되지 않았다면(datetime/datetime2 유형에서 일반적) 매크로에 시간대 인수를 전달하는 대신 SQL 쿼리에서 AT TIME ZONE … AT TIME ZONE 'UTC'로 UTC로 변환하세요.

매크로 설명
$__time(dateColumn) 지정된 열을 _time으로 이름 변경. 예: dateColumn AS time
$__timeEpoch(dateColumn) DATETIME 열을 Unix 타임스탬프로 변환하고 _time으로 이름 변경. 예: DATEDIFF(second, '1970-01-01', dateColumn) AS time
$__timeFilter(dateColumn) 지정된 열에 시간 범위 필터 추가. 예: dateColumn BETWEEN '2017-04-21T05:01:17Z' AND '2017-04-21T05:06:17Z'
$__timeFrom() 현재 시간 범위의 시작 반환. 예: '2017-04-21T05:01:17Z'
$__timeTo() 현재 시간 범위의 끝 반환. 예: '2017-04-21T05:06:17Z'
$__timeGroup(dateColumn, '5m'[, fillValue]) 지정된 시간 열을 간격(예: 5분)으로 그룹화. 선택적으로 0, NULL, previous 같은 값으로 공백 채움. 예: CAST(ROUND(DATEDIFF(second, '1970-01-01', time_column)/300.0, 0) AS bigint) * 300
$__timeGroup(dateColumn, '5m', 0) 위와 동일하되 0으로 누락 데이터 포인트 채움
$__timeGroup(dateColumn, '5m', NULL) 위와 동일하되 NULL로 누락 데이터 포인트 채움
$__timeGroup(dateColumn, '5m', previous) 위와 동일하되 이전 값으로 공백 채움. 이전 값이 없으면 NULL 사용
$__timeGroupAlias(dateColumn, '5m') $__timeGroup과 동일하지만 결과 열에 별칭도 추가
$__unixEpochFilter(dateColumn) Unix 타임스탬프로 시간 범위 필터 추가. 예: dateColumn > 1494410783 AND dateColumn < 1494497183
$__unixEpochFrom() 현재 시간 범위의 시작을 Unix 타임스탬프로 반환. 예: 1494410783
$__unixEpochTo() 현재 시간 범위의 끝을 Unix 타임스탬프로 반환. 예: 1494497183
$__unixEpochNanoFilter(dateColumn) 나노초 정밀도 Unix 타임스탬프로 시간 범위 필터 추가. 예: dateColumn > 1494410783152415214 AND dateColumn < 1494497183142514872
$__unixEpochNanoFrom() 현재 시간 범위의 시작을 나노초 Unix 타임스탬프로 반환. 예: 1494410783152415214
$__unixEpochNanoTo() 현재 시간 범위의 끝을 나노초 Unix 타임스탬프로 반환. 예: 1494497183142514872
$__unixEpochGroup(dateColumn, '5m', [fillMode]) $__timeGroup과 동일하되 Unix 타임스탬프용. 선택적 fillMode로 누락 포인트 처리 제어
$__unixEpochGroupAlias(dateColumn, '5m', [fillMode]) 위와 동일하지만 그룹화 열에 별칭 추가

보간된 쿼리 보기

쿼리 편집기에는 패널을 편집하는 동안 쿼리를 실행한 후 나타나는 Generated SQL 링크가 있어요. 이 링크를 클릭하면 Grafana가 실행한 원시 보간 SQL(쿼리 처리 중 확장된 매크로 포함)을 볼 수 있어요.

Table 쿼리

Table 쿼리를 만들려면 쿼리 편집기의 Format 옵션을 Table로 설정해요. 모든 유효한 SQL 쿼리를 작성할 수 있고, Table 패널은 반환된 열과 행으로 결과를 표시해요.

예시:

CREATE TABLE [event] (
  time_sec bigint,
  description nvarchar(100),
  tags nvarchar(100),
)
CREATE TABLE [mssql_types] (
  c_bit bit, c_tinyint tinyint, c_smallint smallint, c_int int, c_bigint bigint, c_money money, c_smallmoney smallmoney, c_numeric numeric(10,5),
  c_real real, c_decimal decimal(10,2), c_float float,
  c_char char(10), c_varchar varchar(10), c_text text,
  c_nchar nchar(12), c_nvarchar nvarchar(12), c_ntext ntext,
  c_datetime datetime,  c_datetime2 datetime2, c_smalldatetime smalldatetime, c_date date, c_time time, c_datetimeoffset datetimeoffset
)

INSERT INTO [mssql_types]
SELECT
  1, 5, 20020, 980300, 1420070400, '$20000.15', '£2.15', 12345.12,
  1.11, 2.22, 3.33,
  'char10', 'varchar10', 'text',
  N'☺nchar12☺', N'☺nvarchar12☺', N'☺text☺',
  GETDATE(), CAST(GETDATE() AS DATETIME2), CAST(GETDATE() AS SMALLDATETIME), CAST(GETDATE() AS DATE), CAST(GETDATE() AS TIME), SWITCHOFFSET(CAST(GETDATE() AS DATETIMEOFFSET), '-07:00')

출력이 있는 예시 쿼리:

SELECT * FROM [mssql_types]

쿼리에서 AS 키워드로 별칭을 정의해 열이나 테이블 이름을 바꿔요.

출력이 있는 예시 쿼리:

SELECT
  c_bit AS [column1], c_tinyint AS [column2]
FROM
  [mssql_types]

시계열 쿼리

참고: UTC가 아닌 시간대를 사용할 때 Grafana의 시간 이동 문제를 피하려면 타임스탬프를 UTC로 저장하세요.

시계열 쿼리를 만들려면 쿼리 편집기의 Format 옵션을 Time series로 설정해요. 쿼리는 time 이름의 열을 포함해야 하며, 여기에는 SQL datetime 값이나 초 단위 Unix epoch 시간을 나타내는 숫자 값이 들어가야 해요. 패널이 데이터를 올바르게 시각화하려면 결과 집합을 time 열로 정렬해야 해요.

시계열 쿼리는 넓은 데이터 프레임 형식으로 결과를 반환해요.

  • time이 아니거나 string 유형이 아닌 모든 열은 데이터 프레임 쿼리 결과의 값 필드로 변환돼요.
  • 모든 문자열 열은 데이터 프레임 쿼리 결과의 필드 라벨로 변환돼요.

SELECT 절에서 매크로 지원을 활성화해 시계열 쿼리 생성을 단순화할 수 있어요. Data operations 드롭다운에서 $__timeGroup이나 $__timeGroupAlias 같은 매크로를 선택한 다음 Column 드롭다운에서 시간 열, Interval 드롭다운에서 시간 간격을 선택해요.

메트릭 쿼리 만들기

역호환성을 위해 다음과 같은 예외가 있어요: metric 이름의 문자열 열이 포함된 3개 열을 반환하는 쿼리. metric 열을 필드 라벨로 변환하는 대신 필드 이름이 되고, 시리즈 이름은 metric 열의 값으로 서식 지정돼요.

기본 시리즈 이름 서식을 선택적으로 사용자 지정하려면 Standard options definitions 참고.

metric 열이 있는 예시:

SELECT
  $__timeGroupAlias(time_date_time, '5m'),
  min("value_double"),
  'min' as metric
FROM test_data
WHERE $__timeFilter(time_date_time)
GROUP BY time
ORDER BY 1

데이터 프레임 결과:

+---------------------+-----------------+
| Name: time          | Name: min       |
| Labels:             | Labels:         |
| Type: []time.Time   | Type: []float64 |
+---------------------+-----------------+
| 2020-01-02 03:05:00 | 3               |
| 2020-01-02 03:10:00 | 6               |
+---------------------+-----------------+

시계열 쿼리 예시

$__timeGroupAlias 매크로의 fill 매개변수를 사용해 null 값을 0으로 변환:

SELECT
  $__timeGroupAlias(createdAt, '5m', 0),
  sum(value) as value,
  hostname
FROM test_data
WHERE
  $__timeFilter(createdAt)
GROUP BY
  time,
  hostname
ORDER BY 1

다음 예시의 데이터 프레임 결과와 그래프 패널을 사용하면 value 10.0.1.1value 10.0.1.2 이름의 두 시리즈를 얻어요. 시리즈를 10.0.1.110.0.1.2 이름으로 렌더링하려면 Standard options definitions의 표시 이름 값 ${__field.labels.hostname}를 사용해요.

데이터 프레임 결과:

+---------------------+---------------------------+---------------------------+
| Name: time          | Name: value               | Name: value               |
| Labels:             | Labels: hostname=10.0.1.1 | Labels: hostname=10.0.1.2 |
| Type: []time.Time   | Type: []float64           | Type: []float64           |
+---------------------+---------------------------+---------------------------+
| 2020-01-02 03:05:00 | 3                         | 4                         |
| 2020-01-02 03:10:00 | 6                         | 7                         |
+---------------------+---------------------------+---------------------------+

여러 열 사용:

SELECT
  $__timeGroupAlias(time_date_time, '5m'),
  min(value_double) as min_value,
  max(value_double) as max_value
FROM test_data
WHERE $__timeFilter(time_date_time)
GROUP BY time
ORDER BY 1

데이터 프레임 결과:

+---------------------+-----------------+-----------------+
| Name: time          | Name: min_value | Name: max_value |
| Labels:             | Labels:         | Labels:         |
| Type: []time.Time   | Type: []float64 | Type: []float64 |
+---------------------+-----------------+-----------------+
| 2020-01-02 03:04:00 | 3               | 4               |
| 2020-01-02 03:05:00 | 6               | 7               |
+---------------------+-----------------+-----------------+

어노테이션

Microsoft SQL Server 쿼리를 어노테이션 소스로 사용해 대시보드 그래프에 이벤트를 겹칠 수 있어요. 자세한 지침, 쿼리 예시, 모범 사례는 Microsoft SQL Server 어노테이션을 참고하세요.

저장 프로시저 사용

저장 프로시저는 Grafana 쿼리와 함께 동작하는 것으로 검증됐어요. 다만 저장 프로시저에 대한 특별한 처리나 확장 지원은 없으므로 일부 가장자리 경우가 예상대로 동작하지 않을 수 있다는 점을 알아두세요.

저장 프로시저는 반환된 데이터가 이 문서의 관련 이전 섹션에서 설명한 예상 열 이름과 형식과 일치한다면 table, time series, annotation 쿼리에서 사용할 수 있어요.

참고: Grafana 매크로 함수는 저장 프로시저 내부에서 동작하지 않아요.

다음 예시를 위해 데이터베이스 테이블이 Time series queries에 정의돼 있다고 가정해요. 그래프 패널에서 valueOne, valueTwo, measurement 열의 모든 조합처럼 4개 시리즈를 시각화하고 싶다고 해요. 이를 해결하려면 두 개의 쿼리를 사용해야 해요.

첫 번째 쿼리:

SELECT
  $__timeGroup(time, '5m') as time,
  measurement + ' - value one' as metric,
  avg(valueOne) as valueOne
FROM
  metric_values
WHERE
  $__timeFilter(time)
GROUP BY
  $__timeGroup(time, '5m'),
  measurement
ORDER BY 1

두 번째 쿼리:

SELECT
  $__timeGroup(time, '5m') as time,
  measurement + ' - value two' as metric,
  avg(valueTwo) as valueTwo
FROM
  metric_values
GROUP BY
  $__timeGroup(time, '5m'),
  measurement
ORDER BY 1

epoch 시간 형식의 저장 프로시저

그래프 패널에서 여러 시리즈(예: 4개)를 렌더링하는 데 필요한 모든 데이터를 반환하도록 저장 프로시저를 정의할 수 있어요.

다음 예시에서 저장 프로시저는 @from@to라는 두 매개변수를 받으며, 둘 다 int 유형이에요. 이 매개변수들은 epoch 시간 형식의 시간 범위(from/to)를 나타내며 프로시저가 반환하는 결과를 필터링하는 데 사용돼요.

프로시저 내부의 쿼리는 타임스탬프를 5분 간격으로 그룹화해 $__timeGroup(time, '5m')의 동작을 시뮬레이션해요. 시간 그룹화 표현식은 다소 장황하지만 재사용 가능한 SQL Server 함수로 추출해 프로시저를 단순화할 수 있어요.

CREATE PROCEDURE sp_test_epoch(
  @from int,
  @to 	int
)	AS
BEGIN
  SELECT
    cast(cast(DATEDIFF(second, {d '1970-01-01'}, DATEADD(second, DATEDIFF(second,GETDATE(),GETUTCDATE()), time))/600 as int)*600 as int) as time,
    measurement + ' - value one' as metric,
    avg(valueOne) as value
  FROM
    metric_values
  WHERE
    time >= DATEADD(s, @from, '1970-01-01') AND time <= DATEADD(s, @to, '1970-01-01')
  GROUP BY
    cast(cast(DATEDIFF(second, {d '1970-01-01'}, DATEADD(second, DATEDIFF(second,GETDATE(),GETUTCDATE()), time))/600 as int)*600 as int),
    measurement
  UNION ALL
  SELECT
    cast(cast(DATEDIFF(second, {d '1970-01-01'}, DATEADD(second, DATEDIFF(second,GETDATE(),GETUTCDATE()), time))/600 as int)*600 as int) as time,
    measurement + ' - value two' as metric,
    avg(valueTwo) as value
  FROM
    metric_values
  WHERE
    time >= DATEADD(s, @from, '1970-01-01') AND time <= DATEADD(s, @to, '1970-01-01')
  GROUP BY
    cast(cast(DATEDIFF(second, {d '1970-01-01'}, DATEADD(second, DATEDIFF(second,GETDATE(),GETUTCDATE()), time))/600 as int)*600 as int),
    measurement
  ORDER BY 1
END

그런 다음 그래프 패널에서 다음 쿼리로 Grafana가 시간 범위를 동적으로 채운 저장 프로시저를 호출할 수 있어요.

DECLARE
  @from int = $__unixEpochFrom(),
  @to int = $__unixEpochTo()

EXEC dbo.sp_test_epoch @from, @to

이것은 Grafana 내장 매크로로 선택한 시간 범위를 epoch 시간($__unixEpochFrom()$__unixEpochTo())으로 변환하고 입력 매개변수로 저장 프로시저에 전달해요.

datetime 형식의 저장 프로시저

그래프 패널에서 4개 시리즈를 렌더링하는 데 필요한 모든 데이터를 반환하도록 저장 프로시저를 정의할 수 있어요.

다음 예시에서 저장 프로시저는 datetime 유형의 @from@to라는 두 매개변수를 받아요. 이 매개변수들은 선택한 시간 범위를 나타내며 반환 데이터를 필터링하는 데 사용돼요.

프로시저 내부의 쿼리는 데이터를 5분 간격으로 그룹화해 $__timeGroup(time, '5m')의 동작을 모방해요. 이 표현식들은 장황할 수 있지만 가독성과 유지보수를 위해 재사용 가능한 SQL Server 함수로 추출할 수 있어요.

CREATE PROCEDURE sp_test_datetime(
  @from datetime,
  @to 	datetime
)	AS
BEGIN
  SELECT
    cast(cast(DATEDIFF(second, {d '1970-01-01'}, time)/600 as int)*600 as int) as time,
    measurement + ' - value one' as metric,
    avg(valueOne) as value
  FROM
    metric_values
  WHERE
    time >= @from AND time <= @to
  GROUP BY
    cast(cast(DATEDIFF(second, {d '1970-01-01'}, time)/600 as int)*600 as int),
    measurement
  UNION ALL
  SELECT
    cast(cast(DATEDIFF(second, {d '1970-01-01'}, time)/600 as int)*600 as int) as time,
    measurement + ' - value two' as metric,
    avg(valueTwo) as value
  FROM
    metric_values
  WHERE
    time >= @from AND time <= @to
  GROUP BY
    cast(cast(DATEDIFF(second, {d '1970-01-01'}, time)/600 as int)*600 as int),
    measurement
  ORDER BY 1
END

그래프 패널에서 저장 프로시저를 호출하려면 Grafana 내장 매크로로 시간 범위를 동적으로 채우는 다음 쿼리를 사용해요:

DECLARE
  @from datetime = $__timeFrom(),
  @to datetime = $__timeTo()

EXEC dbo.sp_test_datetime @from, @to

다음 단계

쿼리를 만든 뒤에는:

더 알아보기 (Learn more)