2014-05-05 11 views
5

वर्तमान में मैं league_standing नामक एक तालिका का उपयोग करके नीचे दिए गए परिणाम को प्राप्त कर रहा हूं और प्रत्येक मैच के बाद इसे अपडेट कर रहा हूं। मैं तालिका matches के खिलाफ एक प्रश्न के साथ करने में सक्षम होना चाहता हूं।दो कॉलम में मौजूद विदेशी कुंजी द्वारा कॉलम कैसे समेटें?

enter image description here

Teams एक दूसरे को दो बार, दोनों घर में और बाहर खेलते हैं। गौर करें कि team_id दो कॉलम में है home_team_id और away_team_id

+----------------------------------+ 
|    Matches    | 
+----------------------------------+ 
| id        | 
| league_id (FK League)   | 
| season_id (FK Season)   | 
| home_team_id (FK Team)   | 
| away_team_id (FK Team)   | 
| home_score      | 
| away_score      | 
| confirmed      | 
+----------------------------------+ 

यहाँ मैं क्या कोशिश की, लेकिन विफल रहे हैं:

select team.name, HomePoints + AwayPoints points 
from team join (
    select team.id, 
     sum(case when home.home_score > home.away_score then 3 
      when home.home_score = home.away_score then 1 else 0 end) HomePoints, 
     sum(case when away.away_score > away.home_score then 3 else 0 end) AwayPoints 
    from team 
    join matches home on team.id = home.home_team_id 
    join matches away on team.id = away.away_team_id 
    WHERE home.league_id = 94 
     AND home.season_id = 82 
     AND home.confirmed IS NOT NULL 
    group by id 
) temp on team.id = temp.id 
order by points desc; 

यह मुझे दे रहा है गलत अंक:

enter image description here

और यह मुझे होम टीम के लीग_स्टैंडिंग का सही परिणाम देता है केवल

SELECT * FROM 
(
    SELECT team.name, home_team_id AS team_id, 
     COUNT(*) AS played, 
     SUM((CASE WHEN home_score > away_score THEN 1 ELSE 0 END)) AS won, 
     SUM((CASE WHEN away_score > home_score THEN 1 ELSE 0 END)) AS lost, 
     SUM((CASE WHEN home_score = away_score THEN 1 ELSE 0 END)) AS drawn, 
     SUM(home_score) AS goalsFor, 
     SUM(away_score) AS goalsAgainst, 
     SUM(home_score - away_score) AS goalDifference, 
     SUM((CASE WHEN home_score > away_score THEN 3 WHEN home_score = away_score THEN 1 ELSE 0 END)) AS points 
    FROM matches 
    INNER JOIN team ON matches.home_team_id = team.id 
    WHERE league_id = 94 
     AND season_id = 82 
     AND confirmed IS NOT NULL 
    GROUP BY home_team_id 
UNION 
    SELECT team.name, away_team_id AS team_id, 
     COUNT(*) AS played, 
     SUM((CASE WHEN away_score > home_score THEN 1 ELSE 0 END)) AS won, 
     SUM((CASE WHEN home_score > away_score THEN 1 ELSE 0 END)) AS lost, 
     SUM((CASE WHEN home_score = away_score THEN 1 ELSE 0 END)) as drawn, 
     SUM(away_score) AS goalsFor, 
     SUM(home_score) AS goalsAgainst, 
     SUM(away_score - home_score) AS goalDifference, 
     SUM((CASE WHEN away_score > home_score THEN 3 WHEN away_score = home_score THEN 1 ELSE 0 END)) AS points 
    FROM matches 
    INNER JOIN team ON matches.away_team_id = team.id 
    WHERE league_id = 94 
     AND season_id = 82 
     AND confirmed IS NOT NULL 
    GROUP BY away_team_id 
) x 
GROUP BY team_id 
ORDER BY points DESC; 

enter image description here

यदि यह मदद करता है, मेरी डेटाबेस स्कीमा:

enter image description here

मैं अटक रहा हूँ! आशा है कि आप मदद कर सकते हैं।

+1

ऐसा मत करो। डेटाबेस सामान्यीकरण के नियमों में से एक गणना गणना मूल्यों को संग्रहित नहीं करना है। आप अन्य टेबल पर एक चुनिंदा क्वेरी चलाकर हमेशा स्टैंडिंग प्रस्तुत कर सकते हैं। –

+0

@DanBracuk तो मैचों पर एक चुनिंदा क्वेरी चलाने के लिए बेहतर होगा और फिर स्टैंडिंग की गणना करने के लिए PHP का उपयोग करें? – Jonathan

उत्तर

1

मैं प्रत्येक टीम के लिए घर और दूर परिणामों की गणना करता हूं, और फिर एकत्रीकरण करता हूं। निम्नलिखित क्वेरी आपको जो चाहिए वह करना चाहिए। टीम का नाम प्राप्त करने के लिए आपको टीम टेबल के साथ परिणामों में शामिल होने की आवश्यकता है। सिंटैक्स PostgreSQL के लिए काम कर रहा है, हो सकता है कि आपको mysql के लिए कुछ बदलना होगा।

select team_id, count(*) as P, sum(W) as W, sum(D) as D, sum(L) as L, sum(GF) as GF, sum(GA) as GA, sum(GD) as GD, sum(PTS) as PTS from (
select home_team_id as team_id,  
     case when home_score > away_score then 1 
      else 0 end as W, 
     case when home_score = away_score then 1 
      else 0 end as D, 
     case when home_score < away_score then 1 
      else 0 end as L, 
     home_score as GF, 
     away_score as GA, 
     home_score-away_score as GD, 
     case when home_score > away_score then 3 
      when home_score = away_score then 1 
      else 0 end as PTS    
from matches 
where league_id = 94 and season_id = 82 and confirmed is not null 
union all 
select away_team_id as team_id,  
     case when home_score < away_score then 1 
      else 0 end as W, 
     case when home_score = away_score then 1 
      else 0 end as D, 
     case when home_score > away_score then 1 
      else 0 end as L, 
     away_score as GF, 
     home_score as GA, 
     away_score-home_score as GD, 
     case when home_score < away_score then 3 
      when home_score = away_score then 1 
      else 0 end as PTS    
from matches 
where league_id = 94 and season_id = 82 and confirmed is not null 
) as results 
group by team_id 
order by pts DESC,gd DESC,gf DESC; 

वैसे, मुझे नहीं लगता कि किसी तालिका में परिणाम भंडारण और प्रत्येक मैच के बाद उन्हें अद्यतन करने एक बुरा विचार है। हमेशा एक ही परिणाम का पुनर्मूल्यांकन करना कुछ ऐसा है जो टालना चाहिए, विशेष रूप से यदि रैंक से परामर्श करने में रुचि रखने वाले बहुत से उपयोगकर्ता हैं।

+0

धन्यवाद! मुझे लगता है मैं LeagueStanding तालिका के साथ रह सकते हैं, लेकिन मैं खेल x अंतिम की स्टैंडिंग जो मौसम भर में गतिशील होगा दिखाने के लिए एक सुविधा को लागू करने के लिए तो यह प्रयोग करेंगे चाहते हैं! – Jonathan

+0

यदि संघ इसे अनुमति नहीं देता है तो आप इस क्वेरी को कैसे जोड़ते हैं और इस सीमा तक सीमित कैसे करते हैं? मान लें कि मैं पिछले 5 खेलों के आधार पर स्टैंडिंग प्राप्त करना चाहता हूं? – Jonathan

+0

आप कुछ खेल के आधार पर खड़े गणना करने के लिए चाहते हैं, आप सीमा खंड जरूरत नहीं है। आप जहां खंड में एक विशिष्ट शर्त के साथ मेल खाता है फिल्टर करने के लिए, उदाहरण के लिए, ... जहां के लिए की जरूरत है ... और इस बात की पुष्टि रिक्त नहीं है और ( और के बीच) आप गणना करने के लिए चाहते हैं क्वेरी अपने आप में पिछले खेल, तुम दोनों सबक्वेरी की जहां खंड में एक अतिरिक्त सबक्वेरी डालना होगा। मेरा सुझाव यह करने के लिए नहीं है, लेकिन पहले से मेल खाता है जिसमें आप रुचि रखते हैं और फिर जहां खंड में एक साधारण हालत को जोड़ने के लिए कर रहे हैं की तारीख अंतराल गणना करने के लिए। – maxvv

संबंधित मुद्दे