Вставка и преобразование данных из таблицы SQL - PullRequest
1 голос
/ 01 сентября 2011

У меня есть вопрос, который беспокоит меня уже пару дней. У меня есть таблица с:

  • Дата
  • ID
  • Status_ID
  • Start_Time
  • END_TIME
  • Status_Time (секунды) (как они были в определенном состоянии, в секундах)

Я хочу поместить эти данные в другую таблицу, в которой Status_ID сгруппирован в виде столбцов. Эта таблица имеет следующие столбцы:

  • Дата
  • Обед (в секундах)
  • Перерыв (в секундах)
  • Отпуск, (в секундах) и т. Д.

Итак, Status_ID 2 и 3 могут быть сгруппированы по отпуску, Status_ID 1 обед и т. Д.

Я думал о том, чтобы делать Case, вложенный в цикл while, чтобы пройти через все строки, чтобы вставить их в мою другую таблицу. Однако я не могу обернуться, вставляя эти данные из Status_ID в строках в столбцы, по которым они теперь сгруппированы.

Ответы [ 2 ]

2 голосов
/ 01 сентября 2011

Нет необходимости в петле WHILE.

SELECT
    date,
    id,
    SUM(CASE WHEN status_id = 1 THEN status_time ELSE 0 END) AS lunch,
    SUM(CASE WHEN status_id = 2 THEN status_time ELSE 0 END) AS break,
    SUM(CASE WHEN status_id = 3 THEN status_time ELSE 0 END) AS vacation
FROM
    My_Table
GROUP BY
    date,
    id

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

0 голосов
/ 02 сентября 2011

Этот тип запроса (который транспонирует значения из строк в столбцы) называется сводным запросом (SQL Server) или кросс-таблицей (Access).

Существует два типа сводных запросов (вообще говоря):

  1. С фиксированным количеством столбцов.
  2. С динамическим числом столбцов.

SQL Server поддерживает оба типа, но:

  • Database Engine (язык запросов: T-SQL) поддерживает напрямую только сводную запросы с фиксированным числом столбцов (1) и косвенно (2)
  • Службы Analysis Services (язык запросов: MDX) поддерживают напрямую оба типа (1 и 2). Кроме того, вы можете запросить (MDX) источники данных службы анализа из T-SQL, используя функции OPENQUERY / OPENROWSET или используя связанный сервер с именами из четырех частей.

Решения T-SQL (только):

Для первого типа (1), начиная с SQL Server 2005, вы можете использовать оператор PIVOT:

SELECT pvt.*
FROM
(
SELECT Date, Id, Status_ID, Status_Time
FROM Table
) src
PIVOT ( SUM(src.Status_Time) FOR src.Status_ID IN ([1], [2], [3]) ) pvt

или

SELECT pvt.Date, pvt.Id, pvt.[1] AS Lunch, pvt.[2] AS [Break], pvt.[3] Vacation
FROM
(
SELECT Date, Id, Status_ID, Status_Time
FROM Table
) src
PIVOT ( SUM(src.Status_Time) FOR src.Status_ID IN ([1], [2], [3]) ) pvt

Для динамического числа столбцов (2) T-SQL предлагает только косвенное решение: динамические запросы. Сначала вы должны найти все отличные значения от Status_ID, а следующий шаг - построить окончательный запрос:

    DECLARE @SQLStatement NVARCHAR(4000)
            ,@PivotValues NVARCHAR(4000);
    SET @PivotValues = '';

    SELECT  @PivotValues = @PivotValues + ',' + QUOTENAME(src.Status_ID)
    FROM
    (
            SELECT DISTINCT Status_ID
            FROM Table
    ) src;
    SET @PivotValues = SUBSTRING(@PivotValues,2,4000);

    SELECT  @SQLStatement = 
    'SELECT pvt.*
    FROM
    (
    SELECT Date, Id, Status_ID, Status_Time
    FROM Table
    ) src
    PIVOT ( SUM(src.Status_Time) FOR src.Status_ID IN ('+@PivotValues+') ) pvt';

    EXECUTE sp_executesql @SQLStatement; 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...