Soru Çoklu sütun ASC ve DESC BY MySQL SİPARİŞ


2 MYSQL tablom var kullanıcılar ve Skorlar. Detay:

  • kullanıcı tablosu:

enter image description here

  • puan tablosu:

enter image description here

Benim niyetim 20 kullanıcı listesi almak puan alan sıralama DESC (azalan) birleştirir avg_time alan sıralama ASC (artan). Sorguyu kullanıyorum:

SELECT users.username, scores.point, scores.avg_time
FROM scores, users
WHERE scores.user_id = users.id
GROUP BY users.username
ORDER BY scores.point DESC, scores.avg_time
LIMIT 0, 20

Sonuç:

enter image description here

Sonuç yanlıştır çünkü ilk satır tam olarak = 100 ve avg_time = 60'dır.

İstediğim sonuç:

username    point    avg_time
demo123      100        60
demo123456   100       100
demo         90        120

Farklı sorgularla birçok kez denedim, ancak sonuç hala yanlış. Bana bazı çözümler verebilir misiniz?

Şimdiden teşekkürler!


27
2017-12-04 01:49


Menşei


Namxee'nin ima ettiği gibi, kullanıcı başına birden çok satırınız var. Her kullanıcı "avg_time" ve "point" sütunlarının ortalamasını ister misiniz? ve sipariş sonuçlarını kriterler olarak mı kullanıyorsunuz? Değilse, lütfen beklediğiniz şeylerin örnek bir sonucunu gösterin. - DRapp
@DRapp: Her kullanıcının "avg_time" ve "point" sütunlarının ortalamasını istemiyorum. Ben sadece "nokta" alanı DESC (azalan) sıralamak ve "avg_time" alan sıralama ASC (artan) birleştirmek istiyorum. İstediğim sonucu düzenledim. Kötü ingilizcem için özür dilerim. - Tan Viet
Olası kopya İki Sütun PHP MySQL Siparişi - Jim Fell


Cevaplar:


Tamam, şimdi ne istediğini anlıyorum ve sorgulamadan önce onaylamak için açıklığa kavuşturmama izin verin. Her kullanıcı için 1 kayıt istiyorsun. Her kullanıcı için EN İYİ POINTS puan rekorunu istiyorsunuz. Kullanıcı başına en iyi puanlardan en iyi ortalama zamanı olanı istersiniz. Tüm kullanıcıların "en iyi" değerlerine sahip olduktan sonra, en iyi sonuçları ilk sıraya göre sıralamak istersiniz ... Neredeyse bir yarışmadaki sıralama gibi.

Yani şimdi sorgu. Yukarıdaki ifadenin doğru olması durumunda, kişi başına en iyi puan / ortalama süreyi almanız ve o girişe "Sıralama" atamanız gerekir. Bu MySQL @ değişkenleri kullanılarak kolayca yapılabilir. Ardından, yalnızca bu kayıtları her kişi için 1 olarak tutmak için bir HAVING yan tümcesi ekleyin. Son olarak, siparişi en iyi puanlara ve en kısa ortalama süreye göre uygulayın.

select
      U.UserName,
      PreSortedPerUser.Point,
      PreSortedPerUser.Avg_Time,
      @UserRank := if( @lastUserID = PreSortedPerUser.User_ID, @UserRank +1, 1 ) FinalRank,
      @lastUserID := PreSortedPerUser.User_ID
   from
      ( select
              S.user_id,
              S.point,
              S.avg_time
           from
              Scores S
           order by
              S.user_id,
              S.point DESC,
              S.Avg_Time ) PreSortedPerUser
         JOIN Users U
            on PreSortedPerUser.user_ID = U.ID,
      ( select @lastUserID := 0,
               @UserRank := 0 ) sqlvars 
   having
      FinalRank = 1
   order by
      Point Desc,
      Avg_Time

SQLFiddle tarafından ele alınan sonuçlar

Yanıtı almak için gereken satır içi @variables nedeniyle, her satırın sonunda iki tane ekstra sütun vardır. Bunlar sadece "soldan" ve yapmaya çalıştığınız herhangi bir gerçek çıktı sunumunda göz ardı edilebilir ... VEYA, istediğin birkaç sütunu elde etmek için tüm şeyi bir seviye daha üstüne sarabilirsin.

select 
      PQ.UserName,
      PQ.Point,
      PQ.Avg_Time
   from
      ( entire query above pasted here ) as PQ

23
2017-12-04 11:39



Aslında çok akıllı geliştiricisin. Benim küçük ingilizce kelime dağarcığım nedeniyle niyetimi açıklamak oldukça zor. Bu ihtiyacım olan cevap. Cevabınızda açık bir şekilde açıkladığınız için teşekkürler! :) - Tan Viet
@TanViet, yardım etmekten çok mutlu ve bunu geleceğe yönelik bir rehber olarak kullanıyor. Örnek verilere sahip olmak ve ne istediğinizi öğrenmek büyük bir yardımdır. Ayrıca, temelini açık tutunuz Nihai (bu durumda), her kişi başına sadece en iyi rekoru almadan önce arıyorum. İngilizcenize gelince, iyi yaptın. Fikrinizi ve çözümünüzü aldınız, bu yüzden endişelenmeyin. - DRapp


Bence tablo ilişkilerini anlayamıyorum ..

Kullanıcılar: puan = 1: *

sadece join bir çözüm değil.

bu senin niyetin mi?

SELECT users.username, avg(scores.point), avg(scores.avg_time)
FROM scores, users
WHERE scores.user_id = users.id
GROUP BY users.username
ORDER BY avg(scores.point) DESC, avg(scores.avg_time)
LIMIT 0, 20

(Bu sorgu, her kullanıcı için ortalama nokta ve ortalama avg_time ayıklama noktasına göre, asc) avg_time

Her puan sıralamasını almak istiyorsanız? kullanım left outer join

SELECT users.username, scores.point, scores.avg_time
FROM scores left outer join users on scores.user_id = users.id
ORDER BY scores.point DESC, scores.avg_time
LIMIT 0, 20

1
2017-12-04 01:56



Lütfen açık kullanarak tekrar yazınız JOIN sözdizimi. - Kermit
@namxee: Tablo ilişkisini anlıyorum ama neden sorguda avg () işlevini kullandığınızı anlamıyorum. Bana açıklayabilir misin? - Tan Viet
@TanViet: skor tablosunda aynı user_id'in birden çok kaydı vardır. Yani sadece iki tabloya JOIN. user_id benzersiz bir kayıt değildir. her neyse, her bir kullanıcının ortalama puanını ve avg_time değerini almayı düşündüm. - namxee
Duydum Bayan Anladım. Bence o bir arkadaşı Özel parçalar - Bohemian♦
@namxee: Teşekkürler! Her kullanıcının "avg_time" ve "point" sütunlarının ortalamasını istemiyorum. Ben sadece "nokta" alanı DESC (azalan) sıralamak ve "avg_time" alan sıralama ASC (artan) birleştirmek istiyorum. - Tan Viet


@DRapp bir dahidir. Onun SQL'ini nasıl kodladığını asla anlamadım, bu yüzden onu kendi anlayışımda kodlamaya çalıştım.


    SELECT 
      f.username,
      f.point,
      f.avg_time
    FROM
      (
      SELECT
        userscores.username,
        userscores.point,
        userscores.avg_time
      FROM
        (
        SELECT
          users.username,
          scores.point,
          scores.avg_time
        FROM
          scores
        JOIN users
        ON scores.user_id = users.id
        ORDER BY scores.point DESC
        ) userscores
      ORDER BY
        point DESC,
        avg_time
      ) f
    GROUP BY f.username
    ORDER BY point DESC

Aynı sonucu kullanıcıya @variables yerine GROUP BY kullanarak verir.


1
2017-07-02 15:19





pk kimliği ile varsayılan siparişe göre grup , sonuç
  username point avg_time
  demo123 100 90 ---> id = 4
  demo123456 100 100 ---> id = 7
  demo 90 120 ---> kimlik = 1
 


0
2017-12-04 08:36