none
Group by ile inner join kullanımı RRS feed

  • Soru

  • merhabalar aşağıdaki view sorgusundada tüm alanları AlisDetay tablosundan çekiyorum ve UrunID alanına göre grupluyorum. ancak uygulamada UrunID'yi değildi ürün adını göstermek istiyorum. bu alanı da Inner Join ile Urunler tablosundan çekmek istiyorum ama hata kodu alıyorum. 

    her iki sorguyu da yazdım yardımlarınız için şimdiden teşekkürler

    Mevcut view sorgusu

    ALTER view [dbo].[AlisAnaliz]
    as
    select UrunID, sum(Miktar) as 'Miktar', sum(ToplamTutar) as 'ToplamTutar', (SUM(ToplamTutar)/sum(Miktar)) as 'OrtalamaMaliyet' from AlisDetay Group By UrunID
    GO

    Yapmaya Çalıştığım

    ALTER view [dbo].[AlisAnaliz]
    as
    select UrunID, u.Adi, sum(Miktar) as 'Miktar', sum(ToplamTutar) as 'ToplamTutar', (SUM(ToplamTutar)/sum(Miktar)) as 'OrtalamaMaliyet' from AlisDetay 
    inner join Urunler u on AlisDetay.UrunID=u.ID
    Group By UrunID
    GO

    Hata kodu.

    Msg 8120, Level 16, State 1, Procedure AlisAnaliz, Line 3 [Batch Start Line 10]
    Column 'Urunler.Adi' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

    20 Nisan 2020 Pazartesi 12:34

Yanıtlar

  • Merhaba,

    Aşağıdaki şekilde değiştirip deneyin.

    ALTER view [dbo].[AlisAnaliz]
    as
    select UrunID, u.Adi, sum(Miktar) as 'Miktar', sum(ToplamTutar) as 'ToplamTutar', (SUM(ToplamTutar)/sum(Miktar)) as 'OrtalamaMaliyet' from AlisDetay 
    inner join Urunler u on AlisDetay.UrunID=u.ID
    Group By UrunID,u.Adi
    GO


    Vedat ÖZER vedatozer@outlook.com

    • Yanıt Olarak Öneren CetinBasoz 20 Nisan 2020 Pazartesi 13:17
    • Yanıt Olarak İşaretleyen ErdenR 20 Nisan 2020 Pazartesi 17:30
    20 Nisan 2020 Pazartesi 13:02
  • Non-aggregate tum kolonlari group by'da listelemelisiniz:

    Group by u.UrunId, u.Adi

    Daha saglam bir sekli, toplama islemini ayrı yapmak. Nedeni de, sum() islemi sonuçları ancak 1-to-many islemlerinde saglikli calisir, onun disindaki join'lerde hatali sonuclar oluşur. Her zaman (ister 1-to-many, ister many-to-many join) belli bir yazım kullanmak daha iyi:

    ALTER VIEW [dbo].[AlisAnaliz]
    AS
    SELECT u.UrunID,
           u.Adi,
           d.Miktar,
           d.ToplamTutar,
           d.OrtalamaMaliyet
    FROM Urunler u
        INNER JOIN
        (
            SELECT UrunID,
                   SUM(Miktar) AS 'Miktar',
                   SUM(ToplamTutar) AS 'ToplamTutar',
                   (SUM(ToplamTutar) / SUM(Miktar)) AS 'OrtalamaMaliyet'
            FROM AlisDetay
            GROUP BY UrunID
        ) d
            ON d.UrunID = u.ID;
    
     

    Tabii bir de boyle seyleri view yapmak yerine TVF yapmak sanki daha iyi. Ornegin, bir UrunId parametresi de ekleyebilirsiniz:

    IF OBJECT_ID(N'dbo.ufn_AlisAnaliz') IS NOT NULL
        DROP FUNCTION dbo.ufn_AlisAnaliz;
    GO
    
    CREATE FUNCTION dbo.ufn_AlisAnaliz
    (
        @urunID INT
    )
    RETURNS TABLE
    AS
    RETURN
    (
        SELECT u.UrunID,
               u.Adi,
               d.Miktar,
               d.ToplamTutar,
               d.OrtalamaMaliyet
        FROM Urunler u
            INNER JOIN
            (
                SELECT UrunID,
                       SUM(Miktar) AS 'Miktar',
                       SUM(ToplamTutar) AS 'ToplamTutar',
                       (SUM(ToplamTutar) / SUM(Miktar)) AS 'OrtalamaMaliyet'
                FROM AlisDetay
                GROUP BY UrunID
            ) d
                ON d.UrunID = u.ID
        WHERE u.UrunId = @urunID
    );
    GO
    



    How to create a Minimal, Reproducible Example
    The way to Go.
    World's most advanced open source (object-) relational Database.
    Flutter (for mobile, for web & desktop.


    Not: Temelin geri zekalı arkadaşı Idris bu mesaja da atlayıp ne kadar aptal oldugunu bir kez daha belgeleyebilir. Kendisinin tek marifeti beni takip edip, neden her soruya cevap verdiğimi, yardım etmeye calistigimi sorgulamaktır. Bu beyinsiz zavallıya, aptal olduğunu hatırlatmayı unutmayınız.

    • Yanıt Olarak Öneren Vedat ÖZER 20 Nisan 2020 Pazartesi 14:44
    • Yanıt Olarak İşaretleyen ErdenR 20 Nisan 2020 Pazartesi 17:30
    20 Nisan 2020 Pazartesi 13:30

Tüm Yanıtlar

  • Merhaba,

    Aşağıdaki şekilde değiştirip deneyin.

    ALTER view [dbo].[AlisAnaliz]
    as
    select UrunID, u.Adi, sum(Miktar) as 'Miktar', sum(ToplamTutar) as 'ToplamTutar', (SUM(ToplamTutar)/sum(Miktar)) as 'OrtalamaMaliyet' from AlisDetay 
    inner join Urunler u on AlisDetay.UrunID=u.ID
    Group By UrunID,u.Adi
    GO


    Vedat ÖZER vedatozer@outlook.com

    • Yanıt Olarak Öneren CetinBasoz 20 Nisan 2020 Pazartesi 13:17
    • Yanıt Olarak İşaretleyen ErdenR 20 Nisan 2020 Pazartesi 17:30
    20 Nisan 2020 Pazartesi 13:02
  • Non-aggregate tum kolonlari group by'da listelemelisiniz:

    Group by u.UrunId, u.Adi

    Daha saglam bir sekli, toplama islemini ayrı yapmak. Nedeni de, sum() islemi sonuçları ancak 1-to-many islemlerinde saglikli calisir, onun disindaki join'lerde hatali sonuclar oluşur. Her zaman (ister 1-to-many, ister many-to-many join) belli bir yazım kullanmak daha iyi:

    ALTER VIEW [dbo].[AlisAnaliz]
    AS
    SELECT u.UrunID,
           u.Adi,
           d.Miktar,
           d.ToplamTutar,
           d.OrtalamaMaliyet
    FROM Urunler u
        INNER JOIN
        (
            SELECT UrunID,
                   SUM(Miktar) AS 'Miktar',
                   SUM(ToplamTutar) AS 'ToplamTutar',
                   (SUM(ToplamTutar) / SUM(Miktar)) AS 'OrtalamaMaliyet'
            FROM AlisDetay
            GROUP BY UrunID
        ) d
            ON d.UrunID = u.ID;
    
     

    Tabii bir de boyle seyleri view yapmak yerine TVF yapmak sanki daha iyi. Ornegin, bir UrunId parametresi de ekleyebilirsiniz:

    IF OBJECT_ID(N'dbo.ufn_AlisAnaliz') IS NOT NULL
        DROP FUNCTION dbo.ufn_AlisAnaliz;
    GO
    
    CREATE FUNCTION dbo.ufn_AlisAnaliz
    (
        @urunID INT
    )
    RETURNS TABLE
    AS
    RETURN
    (
        SELECT u.UrunID,
               u.Adi,
               d.Miktar,
               d.ToplamTutar,
               d.OrtalamaMaliyet
        FROM Urunler u
            INNER JOIN
            (
                SELECT UrunID,
                       SUM(Miktar) AS 'Miktar',
                       SUM(ToplamTutar) AS 'ToplamTutar',
                       (SUM(ToplamTutar) / SUM(Miktar)) AS 'OrtalamaMaliyet'
                FROM AlisDetay
                GROUP BY UrunID
            ) d
                ON d.UrunID = u.ID
        WHERE u.UrunId = @urunID
    );
    GO
    



    How to create a Minimal, Reproducible Example
    The way to Go.
    World's most advanced open source (object-) relational Database.
    Flutter (for mobile, for web & desktop.


    Not: Temelin geri zekalı arkadaşı Idris bu mesaja da atlayıp ne kadar aptal oldugunu bir kez daha belgeleyebilir. Kendisinin tek marifeti beni takip edip, neden her soruya cevap verdiğimi, yardım etmeye calistigimi sorgulamaktır. Bu beyinsiz zavallıya, aptal olduğunu hatırlatmayı unutmayınız.

    • Yanıt Olarak Öneren Vedat ÖZER 20 Nisan 2020 Pazartesi 14:44
    • Yanıt Olarak İşaretleyen ErdenR 20 Nisan 2020 Pazartesi 17:30
    20 Nisan 2020 Pazartesi 13:30
  • Çetin hocam sonuçların hatasız dönmesi önemli tabii. Bu yüzden bu konuda ki uyarınız için ayrıca teşekkür ederim. 
    20 Nisan 2020 Pazartesi 17:38