简体   繁体   中英

Select records / count distinct from another table

I am using coldfusion and SQL server to manage some hockey stats. I have a SQL query that is performing poorly because I run another query within the actual loop where I return the results. I know this is no good and the performance is lagging. So I am hoping someone can help me do this right.

My first SQL looks like this:

    SELECT
    S.GameID,
    S.LeagueID,
    S.SeasonID, 
    S.DatePlayed, 
    S.TimePlayed, 
    S.HomeTeamID, 
    S.VisitorTeamID, 
    HomeTeam.TeamName AS HomeTeamName, 
    VisitorTeam.TeamName AS VisitorTeamName 
    FROM schedules S 
    JOIN teams AS HomeTeam ON S.HomeTeamID = HomeTeam.TeamID   
    JOIN teams AS VisitorTeam ON S.VisitorTeamID = VisitorTeam.TeamID 
    WHERE S.LeagueID = <cfqueryparam value="#application.leagueid#" cfsqltype="cf_sql_integer">
    AND S.SeasonID = <cfqueryparam value="#application.seasonid#" cfsqltype="cf_sql_integer">
    ORDER BY S.GameID DESC

This runs pretty fast and we are good with that. But then the admins want to show which of the scheduled games have stats assigned to them. So I cfoutput the query and within the loop, I run another query that uses the gameid to check the gamestats table.

    <cfoutput query="qListGames">
    *** table stuff here...
    <cfquery name="qCheckStats" datasource="#APPICATION.DSN#">
    SELECT GameID 
    FROM dbo.GameStats
    WHERE GameID = #qListGames.GameID#
    </cfquery>
    <cfif IsDefined("qAssigned.RecordCount") AND qAssigned.RecordCount GT "0">
    True
    <cfelse>
    False
    </cfif> 
    </cfoutput>

This of course causes major lag as there are 100s of records and I am hitting the database over and over. Ideally, I would like to run a single SQL statement that can gather all of the records I need to show, but also check the gamestats table for a correlating record. I need to show true if gamestats are found or false if they are not. I cannot wrap my head around the SQL needed to make this happen.

Can anyone advise me? Thank you.

You just need an OUTER JOIN (often abbreviated to LEFT JOIN or RIGHT JOIN ) to the GameStats table. There are several ways to get your data; you could just select GameStats.GameID using a column alias (to avoid conflicting with Schedules.GameID) and check whether it is null or has a value in your cfoutput . Or you could select the output you need directly in your query and remove the logic from the loop entirely:

SELECT
    S.GameID,
    S.LeagueID,
    S.SeasonID, 
    S.DatePlayed, 
    S.TimePlayed, 
    S.HomeTeamID, 
    S.VisitorTeamID, 
    HomeTeam.TeamName AS HomeTeamName, 
    VisitorTeam.TeamName AS VisitorTeamName,
    CASE WHEN gs.GameID IS NULL THEN 'False' ELSE 'True' END AS HasGameStats
FROM schedules S
INNER JOIN teams AS HomeTeam ON S.HomeTeamID = HomeTeam.TeamID   
INNER JOIN teams AS VisitorTeam ON S.VisitorTeamID = VisitorTeam.TeamID
    LEFT JOIN GameStats gs ON s.GameID = gs.GameID
WHERE S.LeagueID = <cfqueryparam value="#application.leagueid#" cfsqltype="cf_sql_integer">
    AND S.SeasonID = <cfqueryparam value="#application.seasonid#" cfsqltype="cf_sql_integer">
ORDER BY S.GameID DESC

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM