2013-07-08 2 views
0

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

Tr_Date Tr_Time Tr_Data 
20130313 43359 41239 
20130313 45317 46594 
20130313 45920 62223 
20130313 51227 51826 
20130313 51312 51808 
20130313 52131 47516 
20130313 52443 61269 
20130313 52447 63318 
20130313 52453 2709 
20130313 52545 61262 
20130313 52623 21206 
20130313 52655 48123 
20130313 53250 29004 
20130313 53440 55534 
20130313 53503 30380 
20130313 53932 46166 
20130313 54157 2653 
20130313 54325 46262 
20130313 54503 2055 
20130313 54548 18078 
20130313 54557 21660 
20130313 54623 54390 
20130313 54656 46550 
20130313 54700 59238 

Что мне нужно сделать, это отделить Tr_Time на две колонны. Основой будет Tr_Date и Tr_Data. В каждом Tr_Date и Tr_Data, Есть 2 Tr_Time, который я должен разделить на две разные колонки. Фактически это база данных, захваченная с помощью сканирования id в системе timein/out. Однако входы и выходы сохраняются в одном столбце. Я должен сделать разделение в SQL. Чтобы управлять данными для хронометража в системе начисления заработной платы.

Любая помощь будет очень оценена.

Заранее спасибо.

+0

Можете ли вы показать пример вывода? – revoua

+1

Если время IN и OUT сохраняется в одном столбце, то IN заменяется временем OUT? – rajeemcariazo

+0

Данные примера, которые вы показали, не очень помогают. Значения «Tr-Date» одинаковы, и я действительно не в состоянии воспринимать данные в двух других столбцах. Если вы понимаете данные, не будет простой выбор с предложением where? – Nanda

ответ

0

Я не знаю синтаксис SQL-сервера очень хорошо, но я думаю, вы должны использовать GroupBy функцию и функцию MIN/MAX (или First, зависит от типа поля), например, так:

INSERT INTO destTable SELECT 
    Tr_Date, 
    MIN(Tr_Time) as inField, 
    MAX(Tr_Time) as OutField, 
    Tr_Data 
FROM table 
GROUP BY 
    Tr_Date, 
    Tr_Data; 

Если поля не являются целыми числами, которые можно использовать что-то вроде:

INSERT INTO destTable SELECT 
    Tr_Date, 
    FIRST(Tr_Time) as inField, 
    FIRST(Tr_Time) as OutField, 
    Tr_Data 
FROM table 
GROUP BY 
    Tr_Date, 
    Tr_Data; 

И после этого вы должны обновить таблицу следующим образом:

Возможно, у вас должна быть уже определенная таблица destTable (я не знаю), и, возможно, вам следует изменить запрос с помощью синтаксиса, но я думаю, что эта концепция может помочь.

0

Если у вас есть только две строки для каждого Tr_Date, Tr_Data комбинации (IN первый, OUT второй), запрос может выглядеть следующим образом:

WITH CTE AS 
(
    SELECT 
    *, ROW_NUMBER() OVER (PARTITION BY Tr_Date,Tr_Data ORDER BY Tr_Time) RN 
    FROM Table1 
) 
SELECT 
    c_in.Tr_Date 
,c_in.Tr_Data 
,c_in.Tr_Time AS Time_In 
,c_out.Tr_Time AS Time_Out 
FROM CTE c_in 
LEFT JOIN CTE c_out 
    ON c_in.Tr_Date = c_out.Tr_Date 
    AND c_in.Tr_Data = c_out.Tr_Data 
    AND c_in.RN = 1 
    AND c_out.RN = 2 
WHERE c_in.RN = 1 

SQLFiddle DEMO (Данные образцы не имели каких-либо из строк , поэтому я добавил несколько дополнительных строк со случайными числами)

+1

почему не просто 'ВЫБРАТЬ Tr_Date, MIN (Tr_Time), MAX (Tr_Time), Tr_Data ОТ Table1 группы по Tr_Date, Tr_Data 'если он только хочет выбрать? –

+0

@trippino Хорошая точка зрения, я часто упускаю из виду простые решения :) ...Однако, если строка time_out еще не существует, я думаю, что NULL должен быть возвращен, а не в то же время, что и time_in –

0

попробовать этот

SELECT Tr_Date , 
     Tr_Data , 
     MAX(Tr_Time) , 
     MIN(Tr_Time) 
FROM TableName 
GROUP BY Tr_Date , 
     Tr_Data 
Смежные вопросы