none
Gün bazından saat farkını bulmak RRS feed

  • Soru

  • Merhaba Arkadaşlar,

    C#, Ms sql, Şimdiden aynı soruyu sorduğum için kusura bakmayın bu sorumu daha öncede biraz karışık sormuştum sanırım o yüzden yardım alamadım, gün bazından saat farkını bulup oradan da maaş hesaplamaya yapmak istiyorum, aşağıda tabloma gelen verilerim mevcut veriler bir cihazdan dışarıdan eklendiği için  listeye tablodaki gibi düşüyor. Benim sorgumda aynı şekilde geliyor fakat almak istediğim sorgu giriş ve çıkış yani 09:00 dan 18:00 arası ve iki satır veri dönmesi gerekiyor , aşağıda şimdili rastgele tarih verdiğim sanırım bu hatalı bir işlem oluyor sadece saat farkını bu şekilde alabildiğim için ekledim.

    SELECT KARTNO, HAREKET_TARIHI, HAREKET_SAATI, 
    DATEDIFF(HOUR,'10/11/2016 09:00','10/11/2016 18:00') AS SAAT_FARKI FROM HAREKET_AKTARIM

    22 Aralık 2016 Perşembe 21:10

Yanıtlar

  • Dogrusunu istersen istedigin is o kadar da basit degil. Senin oncelikle 1.temel problemini cozmen gerekiyor. 1.problem kayitlarin kartno,giris, cikis seklinde degil ama karno, tarihsaat seklinde olmasi. Aslinda olayi bastan tasarlaman daha iyi olurdu ama madem bununla yasamak zorundasin o cozulmeli:

    DECLARE @tablo TABLE
        (
          KARTNO INT ,
          HAREKET DATETIME
        );
    
    INSERT  @tablo
            ( KARTNO, HAREKET )
    VALUES  ( 1, '20161210 09:00' ),
            ( 1, '20161210 18:00' ),
            ( 1, '20161211 09:00' ),
            ( 1, '20161211 18:00' ),
            ( 2, '20161210 09:00' ),
            ( 2, '20161210 18:00' ),
            ( 2, '20161211 09:00' ),
            ( 2, '20161211 18:00' ),
            ( 1, '20161212 09:00' );
    
    
    WITH    tmp ( recNo, KARTNO, HAREKET )
              AS ( SELECT   ROW_NUMBER() OVER ( PARTITION BY KARTNO ORDER BY HAREKET ) ,
                            KARTNO ,
                            HAREKET
                   FROM     @tablo
                 ),
            cikis ( hareketNo, KARTNO, HAREKET )
              AS ( SELECT   CEILING(recNo / 2.0) ,
                            KARTNO ,
                            HAREKET
                   FROM     tmp
                   WHERE    recNo % 2 = 1
                 ),
            varis ( hareketNo, KARTNO, HAREKET )
              AS ( SELECT   CEILING(recNo / 2.0) ,
                            KARTNO ,
                            HAREKET
                   FROM     tmp
                   WHERE    recNo % 2 = 0
                 )
        SELECT  cikis.hareketNo ,
                cikis.KARTNO ,
                cikis.HAREKET AS Cikis ,
                varis.HAREKET AS Varis
        FROM    cikis
                LEFT JOIN varis ON varis.hareketNo = cikis.hareketNo
                                   AND varis.KARTNO = cikis.KARTNO;
    
    

    Burada temel problemlerden birisi, kayitlarin giris (otobus hareketi gibi geldi ondan cikis varis diye ornek yazdim) ile basladigini varsayiyoruz. Bir baska problem kayitlarin cok duzgun tutuldugunu varsayiyoruz. Benim de gercek hayatta giris-cikis kayitlarim var ve giris ve cikista kredi karti gibi kartlarla, RFID veya benzeri ile yapiliyor. Sonucta orada da benzer sekilde:

    kisiNo, tarihsaat

    var sadece. Benim durumumda kisa bir sure icerisinde ya okumadiysa diye ustuste yapilan okutmalar filan var. Eger sende boyle problemler yoksa yukaridaki varsayimlarla o kod calisir. Geriye DateDiff kalir derdim ama gercek hayatta oyle degil. Isin icine mesai saati sonrasi, haftasonu vs ayrintilar giriyor. Onlar icin de C# forumunda birkac kez giris-cikis isleme ornekleri verildi, onlara bakabilirsin. 

    • Yanıt Olarak İşaretleyen csharpp 23 Aralık 2016 Cuma 20:56
    23 Aralık 2016 Cuma 16:15

Tüm Yanıtlar

  • Merhabalar,

    Anladığım kadarıyla bu paylaştığınız çıktı olmasını istediğiniz çıktı doğru mudur? Peki bu durumda elinizdeki veriler nasıl tutuluyor? Örnek veri paylaşabilir misiniz? Net anlayabilmek açısından...


    Please Mark This As Answer if it solved your issue
    Please Vote This As Helpful if it helps to solve your issue
    www.abdullahaltintas.com

    23 Aralık 2016 Cuma 11:59
  • Abdullah abi istemiş olduğum veriler bunlar değil tablomda bu şekilde data var bu dataları çekip yukar da belitmiş olduğum şekilde yapmak istiyorum. bir personelin giriş çıkış saatleri olduğunu düşünün yukarıdaki data nın gün bazından hesaplayacağım fakat yukarıdaki tablomda ki data her giriş ve çıkışı iki satır halinde attığı için doğru sorguyu alamadım 
    23 Aralık 2016 Cuma 12:40
  • 2 ayrı satırda gelen verileri aslında yan yana getirip işlem yapmak istiyorsun anlaşılan.  (Eğer doğru anladıysam :))

    Bu durumda SQL Server 2012 veya üst versiyonlar kullanıyorsanız SQL'de LEAD() fonksiyonu ile alt satırda bulunan veriyi ilgili satırın yanına getirebilirsiniz. Bunun üzerinden de istediğiniz işlemi devam ettirebilirsiniz:

    SELECT KARTNO, HAREKET_TARIHI, HAREKET_SAATI,
    	LEAD(HAREKET_SAATI) OVER(partition by KARTNO order by HAREKET_TARIHI asc) as CikisSaati
    FROM HAREKET_AKTARIM
    Umarım faydalı olur...


    Please Mark This As Answer if it solved your issue
    Please Vote This As Helpful if it helps to solve your issue
    www.abdullahaltintas.com

    23 Aralık 2016 Cuma 13:21
  • Dogrusunu istersen istedigin is o kadar da basit degil. Senin oncelikle 1.temel problemini cozmen gerekiyor. 1.problem kayitlarin kartno,giris, cikis seklinde degil ama karno, tarihsaat seklinde olmasi. Aslinda olayi bastan tasarlaman daha iyi olurdu ama madem bununla yasamak zorundasin o cozulmeli:

    DECLARE @tablo TABLE
        (
          KARTNO INT ,
          HAREKET DATETIME
        );
    
    INSERT  @tablo
            ( KARTNO, HAREKET )
    VALUES  ( 1, '20161210 09:00' ),
            ( 1, '20161210 18:00' ),
            ( 1, '20161211 09:00' ),
            ( 1, '20161211 18:00' ),
            ( 2, '20161210 09:00' ),
            ( 2, '20161210 18:00' ),
            ( 2, '20161211 09:00' ),
            ( 2, '20161211 18:00' ),
            ( 1, '20161212 09:00' );
    
    
    WITH    tmp ( recNo, KARTNO, HAREKET )
              AS ( SELECT   ROW_NUMBER() OVER ( PARTITION BY KARTNO ORDER BY HAREKET ) ,
                            KARTNO ,
                            HAREKET
                   FROM     @tablo
                 ),
            cikis ( hareketNo, KARTNO, HAREKET )
              AS ( SELECT   CEILING(recNo / 2.0) ,
                            KARTNO ,
                            HAREKET
                   FROM     tmp
                   WHERE    recNo % 2 = 1
                 ),
            varis ( hareketNo, KARTNO, HAREKET )
              AS ( SELECT   CEILING(recNo / 2.0) ,
                            KARTNO ,
                            HAREKET
                   FROM     tmp
                   WHERE    recNo % 2 = 0
                 )
        SELECT  cikis.hareketNo ,
                cikis.KARTNO ,
                cikis.HAREKET AS Cikis ,
                varis.HAREKET AS Varis
        FROM    cikis
                LEFT JOIN varis ON varis.hareketNo = cikis.hareketNo
                                   AND varis.KARTNO = cikis.KARTNO;
    
    

    Burada temel problemlerden birisi, kayitlarin giris (otobus hareketi gibi geldi ondan cikis varis diye ornek yazdim) ile basladigini varsayiyoruz. Bir baska problem kayitlarin cok duzgun tutuldugunu varsayiyoruz. Benim de gercek hayatta giris-cikis kayitlarim var ve giris ve cikista kredi karti gibi kartlarla, RFID veya benzeri ile yapiliyor. Sonucta orada da benzer sekilde:

    kisiNo, tarihsaat

    var sadece. Benim durumumda kisa bir sure icerisinde ya okumadiysa diye ustuste yapilan okutmalar filan var. Eger sende boyle problemler yoksa yukaridaki varsayimlarla o kod calisir. Geriye DateDiff kalir derdim ama gercek hayatta oyle degil. Isin icine mesai saati sonrasi, haftasonu vs ayrintilar giriyor. Onlar icin de C# forumunda birkac kez giris-cikis isleme ornekleri verildi, onlara bakabilirsin. 

    • Yanıt Olarak İşaretleyen csharpp 23 Aralık 2016 Cuma 20:56
    23 Aralık 2016 Cuma 16:15
  • Çetin abi vermiş olduğun örnek çok güzel emeğine sağlık abi ve bende de o problem var üst üst okutma yapabilir şimdi denedim çift kayıt atıyor o zamanda aynı güne ve aynı kart numarasına tek bir kayıt atması gerekiyor biraz uğraştım ama olmadı sanırım bu sorguda o olabilir mi acaba ve şöyle bir durum daha var aslında cihazdan veriler tek satır halinde düşüyor ben onları list e alıp oradan insert yapıyorum , böyle bir durum için nasıl bir senaryo kurulabilir ozaman hem belki sorgu bu kadar kısıtlı kalmaz.
    23 Aralık 2016 Cuma 19:04
  • Tek satir gelmesi normal. Benim yaptigim, once o gelen datadan lokalde bir tablo yaratiyorum ve icini seninkine benzer sekilde o datadan dolduruyorum. Sonra kayitlari inceliyorum, hangisi giris, hangisi cikis, hangisi mukerrer ya da gecersiz diye ve sonucta kisi, giris, cikis listesi seklinde duzgun bir hal aliyor, o halini veritabanina kaydediyorum. 
    23 Aralık 2016 Cuma 19:22
  • yo abi orasını anladım şunu demek istiyorum , adam sabah işe girerken 3 kere giriş yaptıysa yani parmak okuttuysa :) akşamda bir sefer parmak okuttu şimdi liste o zaman bozuluyor aşağıdaki gibi oluyor fakat giriş ve çıkışlar tam girilirse sorun olmuyor bunu nasıl önlerim acaba.

    Giriş

    Sonuç

    • Düzenleyen csharpp 23 Aralık 2016 Cuma 19:31
    23 Aralık 2016 Cuma 19:25
  • YO ABİ
    ?
    23 Aralık 2016 Cuma 19:29
  • Bağlantı kurma şansın varmı abi belki o zaman daha anlaşılır olabilir.
    23 Aralık 2016 Cuma 19:34
  • Hayir mac seyrediyorum. Belki pazartesi.
    23 Aralık 2016 Cuma 19:44
  • :)  Peki abi biraz uğraşayım listeyi göndünüz sanırım sonuç o şekilde dönüyor. iyi seyirler
    23 Aralık 2016 Cuma 19:46
  • Hangi listeyi gordum? Gordugum icin kod verdim zaten.

    not: Bir de actigin konulari kapatmiyorsun.

    23 Aralık 2016 Cuma 19:58
  • abi yo abi demişim ya bakın orda bir yorum yaptım ve sonuç listesini yazdım. bu arada dikkat ederim abim.
    23 Aralık 2016 Cuma 20:08
  • yo abi orasını anladım şunu demek istiyorum , adam sabah işe girerken 3 kere giriş yaptıysa yani parmak okuttuysa :) akşamda bir sefer parmak okuttu şimdi liste o zaman bozuluyor aşağıdaki gibi oluyor fakat giriş ve çıkışlar tam girilirse sorun olmuyor bunu nasıl önlerim acaba.

    Giriş

    Sonuç

    23 Aralık 2016 Cuma 20:08
  • Dedigim gibi aralardaki ekstra okutmalari tespit edip onlari atman gerekiyor. Sen hep resim veriyorsun, ben ise kod :(
    23 Aralık 2016 Cuma 20:28
  • :)  Oldu çetin abi çok teşekkür ederim yardımınız için Allah razı olsun.
    23 Aralık 2016 Cuma 20:56