0

次のSQLクエリがあります。

SELECT E.EMPID, TM.LOGIN, TM.LOGOUT, 
    SUM(DATEDIFF(MINUTE,TM.LOGIN,TM.LOGOUT)/60)+':'+
    SUM(DATEDIFF(MINUTE,TM.LOGIN,TM.LOGOUT)%60) AS WORKEDHOURS   
FROM EMPLOYEE_DETAILS E  
LEFT JOIN TIMING_DETAILS TM  
    ON(E.EMPID=TM.EMPID)  
WHERE TM.LOGIN BETWEEN '2013-09-02' AND DATEADD(DAY, 1, '2013-09-03')  
GROUP BY E.EMPID,TM.LOGIN,TM.LOGOUT  
ORDER BY E.EMPID

上記のクエリを実行すると、次の出力が得られます。

EMPID   LOGIN               LOGOUT          WORKEDHOURS  
1     2-9-2013 9:30      2-9-2013 1:00          3:30
1     2-9-2013 2:00      2-9-2013 6:00          4:00

2     2-9-2013 9:30      2-9-2013 2:00          4:30
2     2-9-2013 3:00      2-9-2013 6:00          3:00

1     3-9-2013 9:30      3-9-2013 6:00          8:30    

しかし、次のように結果を表示したいのですが、誰か助けてください、ありがとう

EMPID   LOGIN               LOGOUT          WORKEDHOURS
1     2-9-2013 9:30      2-9-2013 1:00          7:30
1     2-9-2013 2:00      2-9-2013 6:00          

2     2-9-2013 9:30      2-9-2013 2:00          7:30
2     2-9-2013 3:00      2-9-2013 6:00          

1     3-9-2013 9:30      3-9-2013 6:00          8:30
4

4 に答える 4

0

これを試してみてください -

SELECT  
      t.EMPID
    , t.LOGIN
    , t.LOGOUT
    , WORKEDHOURS = CASE WHEN rn = 1 THEN t.WORKEDHOURS END
FROM (
    SELECT 
          TM2.EMPID
        , TM2.LOGIN
        , TM2.LOGOUT
        , TM.WORKEDHOURS
        , rn = ROW_NUMBER() OVER (PARTITION BY TM2.EMPID ORDER BY TM2.EMPID) 
    FROM dbo.TIMING_DETAILS TM2
    JOIN (
        SELECT 
              EMPID
            , WORKEDHOURS = CAST(SUM(DATEDIFF(MINUTE, [login], LOGOUT)) / 60 AS VARCHAR(100)) + ':' + CAST(SUM(DATEDIFF(MINUTE, [login], LOGOUT)) % 60 AS VARCHAR(10)) 
        FROM dbo.TIMING_DETAILS
        WHERE [login] BETWEEN '20130902' AND '20130904'
        GROUP BY EMPID
    ) TM ON TM2.EMPID = TM.EMPID
    WHERE EXISTS( -- maybe this is unnecessary
         SELECT 1
         FROM dbo.EMPLOYEE_DETAILS E
         WHERE E.EMPID = TM2.EMPID 
    )
) t
于 2013-09-25T06:08:27.997 に答える
0
SELECT E.EMPID, TM.LOGIN, TM.LOGOUT,WORKHOURS_TABLE.WORKEDHOURS

FROM EMPLOYEE_DETAILS E, TIMING_DETAILS TM ,

(SELECT EMPID,
concat(
sum(hour(timeDIFF(TM.LOGOUT, TM.LOGIN )))
+ 
sum(minute(timeDIFF(TM.LOGOUT, TM.LOGIN ))) div 60 ,
":" , 
sum(minute(timeDIFF(TM.LOGOUT, TM.LOGIN ))) % 60
)

AS WORKEDHOURS 
FROM TIMING_DETAILS TM
GROUP BY EMPID) AS WORKHOURS_TABLE

WHERE E.EMPID =  WORKHOURS_TABLE.EMPID AND E.EMPID=TM.EMPID  
ORDER BY E.EMPID

出力は次のようになります。

EMPID   LOGIN               LOGOUT          WORKEDHOURS
1     2-9-2013 9:30      2-9-2013 1:00          7:30
1     2-9-2013 2:00      2-9-2013 6:00          7:30

2     2-9-2013 9:30      2-9-2013 2:00          7:30
2     2-9-2013 3:00      2-9-2013 6:00          7:30

日付でグループ化する場合は、 と の別の列を保持する必要がdateありtime、日付でグループ化できます。

MySQL データベースでクエリを試してみましたが、正常に動作します。あなたはそれを試してみてください。

于 2013-09-25T06:03:25.197 に答える
0

私たちの対話の後、また他の参​​加者とのあなたの対話を見直したところ、あなたの問題はもう少し制約されていることがわかりました. 実際に必要な出力は次のようなものです。

EMPID   DAY          WORKEDHOURS
    1   2-9-2013     7:30
    1   3-9-2013     8:30
    2   2-9-2013     7:30

ケース 1: 範囲内の 1 日

1 日だけに関心がある場合は、結果に日付を挿入するだけです。次のことを試してください。

SELECT E.EMPID,
       '2013-09-02' AS DAY,
       SUM(DATEDIFF(MINUTE,TM.LOGIN,TM.LOGOUT)/60)+':'+
       SUM(DATEDIFF(MINUTE,TM.LOGIN,TM.LOGOUT)%60) AS WORKEDHOURS   
FROM EMPLOYEE_DETAILS E  
     LEFT JOIN TIMING_DETAILS TM  
     ON (E.EMPID=TM.EMPID)  
WHERE TM.LOGIN BETWEEN '2013-09-02' AND DATEADD(DAY, 1, '2013-09-03')
GROUP BY E.EMPID
ORDER BY E.EMPID

問題の日付に名前付きパラメーターを使用するようにクエリを書き直すこともできます。以下に例を示しますが、これを使用するには、値を parameter にバインドする必要がありますTheDay

SELECT E.EMPID,
       @TheDay AS DAY,
       SUM(DATEDIFF(MINUTE,TM.LOGIN,TM.LOGOUT)/60)+':'+
       SUM(DATEDIFF(MINUTE,TM.LOGIN,TM.LOGOUT)%60) AS WORKEDHOURS   
FROM EMPLOYEE_DETAILS E  
     LEFT JOIN TIMING_DETAILS TM  
     ON (E.EMPID=TM.EMPID)  
WHERE TM.LOGIN BETWEEN @TheDay AND DATEADD(DAY, 1, @TheDay)
GROUP BY E.EMPID
ORDER BY E.EMPID

ケース 2: 範囲内の複数日

EMPID ごとに複数の行が必要であるが、そのような行が 1 日に 1 つしかない場合、事態はさらに複雑になります。いくつかの (おそらくすべての) DBMS で可能だと思いますが、移植性のない機能を使用する必要があるかもしれません。必要なのは、日時値GROUP BYの日の部分です。LOGIN

SQL Server 2008 (またはそれ以降) を使用している場合は、次のことを試すことができます。

SELECT E.EMPID,
       CAST(TM.LOGIN AS DATE) AS DAY,
       SUM(DATEDIFF(MINUTE,TM.LOGIN,TM.LOGOUT)/60)+':'+
       SUM(DATEDIFF(MINUTE,TM.LOGIN,TM.LOGOUT)%60) AS WORKEDHOURS   
FROM EMPLOYEE_DETAILS E  
     LEFT JOIN TIMING_DETAILS TM  
     ON (E.EMPID=TM.EMPID)  
WHERE TM.LOGIN BETWEEN '2013-09-02' AND DATEADD(DAY, 1, '2013-09-03')
GROUP BY E.EMPID, CAST(TM.LOGIN AS DATE)
ORDER BY E.EMPID

私はこのクエリをテストする立場にないことに注意してください。たとえば、GROUP BY DAY式を繰り返す代わりに、そうしなければならない場合があります。

ケース 2B: 範囲内の複数日、最初と最後のログイン

EMPID ごとに 1 日 1 行が必要ですが、最初のログイン時間と最後のログアウト時間は必要ですか? 次のことを試すことができます。

SELECT E.EMPID,
       MIN(TM.LOGIN) AS FIRSTLOGIN,
       MAX(TM.LOGOUT) AS LASTLOGOUT,
       SUM(DATEDIFF(MINUTE,TM.LOGIN,TM.LOGOUT)/60)+':'+
       SUM(DATEDIFF(MINUTE,TM.LOGIN,TM.LOGOUT)%60) AS WORKEDHOURS   
FROM EMPLOYEE_DETAILS E  
     LEFT JOIN TIMING_DETAILS TM  
     ON (E.EMPID=TM.EMPID)  
WHERE TM.LOGIN BETWEEN '2013-09-02' AND DATEADD(DAY, 1, '2013-09-03')
GROUP BY E.EMPID, CAST(TM.LOGIN AS DATE)
ORDER BY E.EMPID

繰り返しますが、私はこのクエリをテストする立場にありませんでした。

テスト ケース: Visual Studio 2010 内のローカル SQL Server Express データベースに対するクエリ

今日は Sql Server でテストできませんが、ローカルの Sql Server Express データベースで Visual Studio 2010 の下でテストしたバージョンのクエリを次に示します。

SELECT
    E.EMPID, E.NAME,
    MIN(TM.LOGIN) AS FirstLogIn,
    MAX(TM.LOGOUT) AS LastLogOut,
    CAST(SUM(DATEDIFF(MINUTE, TM.LOGIN, TM.LOGOUT) / 60) AS NVARCHAR)+':'+CAST(SUM(DATEDIFF(MINUTE, TM.LOGIN, TM.LOGOUT) % 60) AS NVARCHAR) AS WorkedHours
FROM
    EMPLOYEE_DETAILS AS E LEFT OUTER JOIN TIMING_DETAILS AS TM ON E.EMPID = TM.EMPID
WHERE
    TM.LOGIN BETWEEN '2013-09-21' AND DATEADD(DAY, 1, '2013-09-22')
GROUP BY
    E.EMPID, E.NAME,
    DATEADD(DAY, DATEDIFF(DAY, 0, TM.LOGIN), 0)
ORDER BY
    E.EMPID, FirstLogin

テスト データ EMPLOYEE_DETAILS:

EMPID    NAME
1        Joe
2        Jane
3        Martha

テストデータ TIMING_DETAILS:

EMPID    LOGIN                    LOGOUT
1        '2013-09-21 09:00:00'    '2013-09-21 10:30:00'
1        '2013-09-21 14:00:00'    '2013-09-21 16:00:00'
1        '2013-09-22 08:30:00'    '2013-09-22 11:00:00'
2        '2013-09-21 10:45:00'    '2013-09-21 13:30:00'

結果:

EMPID    NAME   FirstLogIn               LastLogOut               WorkedHours
1        Joe    '2013-09-21 09:00:00'    '2013-09-21 16:00:00'    3:30
1        Joe    '2013-09-22 08:30:00'    '2013-09-22 11:00:00'    2:30
2        Jane   '2013-09-21 10:45:00'    '2013-09-21 13:30:00'    2:45

それは私には正しいようです。SQL Server Express クエリの唯一の違いは、DATE 型が提供されていないことです。そのため、CAST を変更する必要がありました。ああ、WorkedHours の NVARCHAR にも明示的にキャストする必要がありました。

ご使用の環境に合わせて調整してください。

お役に立てれば。

于 2013-09-26T06:20:06.770 に答える