2015-09-01 5 views
2

Я недавно взял на себя работает внутренние лиги в сквош-клуб я играю вРезультаты Сквош лиги - SQL Query

Я надеялся поставить их в Интернете для пользователей, чтобы просмотреть и добавить результаты в соответствии с требованиями

структура лиги следует ниже формат с 6 лиг

лиги 1

|  | John | Mark | Peter | Martin | Paul | 
|:------:|:----:|:----:|:-----:|:------:|:----:| 
| John | NULL | 3 | 0 | 1 | 2 | 
| Mark | 0 | NULL | 1 | 3 | 0 | 
| Peter | 3 | 3 | NULL | 1 | 3 | 
| Martin | 3 | 1 | 3 | NULL | 2 | 
| Paul | 3 | 3 | 0 | 3 | NULL | 

лиги 2

и т.д. и т.п.

Я разработал структуру таблицы как

CREATE TABLE [dbo].[Results](
    [ResultId] [int] IDENTITY(1,1) NOT NULL, 
    [LeagueId] [int] NOT NULL, 
    [Player1Id] [int] NOT NULL, 
    [Player2Id] [int] NOT NULL, 
    [Player1Result] [int] NULL, 
    [Player2Result] [int] NULL) 

CREATE TABLE [dbo].[Players](
    [PlayerId] [int] IDENTITY(1,1) NOT NULL, 
    [UserId] [int] NOT NULL, 
    [FirstName] [nvarchar](150) NULL, 
    [LastName] [nvarchar](150) NULL) 

CREATE TABLE [dbo].[Leagues](
    [LeagueId] [int] IDENTITY(1,1) NOT NULL, 
    [LeagueName] [nvarchar](50) NULL) 

Я пытаюсь написать запрос, который дает мне выход каждого divsion в одном запросе, а не несколько, чтобы дать мне выход может ли кто-нибудь помочь с запросом?

то, что я до сих пор является

select p.FirstName, p1.player2result, p2.player2result, p3.player2result, p4.player2result 
from 
    (select player2Result from Results p1 where p.playerId = p1.Player2Id 
    union 
    select player2Result from Results p2 where p.playerId = p2.Player2Id 
    union 
    select player2Result from Results p3 where p.playerId = p3.Player2Id 
    union 
    select player2Result from Results p4 where p.playerId = p4.Player2Id) as opResult 
LEFT JOIN Players p on opResult.Player2Result = p.PlayerId 
GROUP BY p.FirstName, p1.player2result, p2.player2result, p3.player2result, p4.player2result 
+0

Я думаю, что ничего не связано с mysql. удалите тег, пожалуйста, тогда. – Alex

ответ

2

Настоящий рабочий пример.

Это сохранит себя в курсе по мере добавления новых имен и т.д., так нет необходимости редактировать SQL каждый раз, когда вы делаете новый плеер ..

Единственная неудача в том, что имя игрока должны быть уникальный !!!!

Я предполагаю, что вы сможете адаптировать это для показа каждой лиги, но если вам нужна помощь в этом, тогда просто спросите.

также обратите внимание, что мои тестовые данные не совпадают с вашими. Я просто составил случайные данные.

------------------------------------------ 
    --Data setup 
    ------------------------------------------ 

    CREATE TABLE [dbo].[Results] 
    (
     [ResultId] [int] IDENTITY(1,1) NOT NULL, 
     [LeagueId] [int] NOT NULL, 
     [Player1Id] [int] NOT NULL, 
     [Player2Id] [int] NOT NULL, 
     [Player1Result] [int] NULL, 
     [Player2Result] [int] NULL 
) 

    CREATE TABLE [dbo].[Players] 
    (
     [PlayerId] [int] IDENTITY(1,1) NOT NULL, 
     [UserId] [int] NOT NULL, 
     [FirstName] [nvarchar](150) NULL, 
     [LastName] [nvarchar](150) NULL 
) 

    CREATE TABLE [dbo].[Leagues] 
    (
     [LeagueId] [int] IDENTITY(1,1) NOT NULL, 
     [LeagueName] [nvarchar](50) NULL 
) 

    INSERT INTO Players (UserId,FirstName) 
    VALUES 
     (1,'John'), 
     (2,'Mark'), 
     (3,'Peter'), 
     (4,'Martin'), 
     (5,'Paul') 

    INSERT INTO Leagues(LeagueName) 
    VALUES 
     ('League 1'), 
     ('League 2') 

    INSERT INTO Results(LeagueId,Player1Id,Player2Id,Player1Result,Player2Result) 
    VALUES 
     (1,1,2,3,0), 
     (1,1,3,0,4), 
     (1,1,4,1,2), 
     (1,1,5,2,1), 
     (1,2,3,1,4), 
     (1,2,4,3,2), 
     (1,2,5,0,1), 
     (1,3,4,1,2), 
     (1,3,5,3,1), 
     (1,4,5,2,1) 

    ------------------------------------------ 
    --Answer 
    ------------------------------------------ 

    --Get a list of all the names in the system 
    DECLARE @Names NVARCHAR(MAX) 

    SET @Names = (SELECT '[' + STUFF((SELECT '],[' + FirstName FROM Players ORDER BY FirstName FOR XML PATH('')),1,3,'') + ']') 

    DECLARE @SQL NVARCHAR(MAX) 

    --Create the matrix 
    SET @SQL = ' 
    SELECT FirstName1,' + @Names + ' 
    FROM 
    (
     SELECT P1.FirstName AS FirstName1,P2.FirstName AS FirstName2,R.Player1Result AS Result 
     FROM Results AS R 
     INNER JOIN Players AS P1 ON P1.PlayerId = R.Player1Id 
     INNER JOIN Players AS P2 ON P2.PlayerId = R.Player2Id 

     UNION ALL 

     SELECT P2.FirstName AS FirstName1,P1.FirstName AS FirstName2,R.Player2Result AS Result 
     FROM Results AS R 
     INNER JOIN Players AS P1 ON P1.PlayerId = R.Player1Id 
     INNER JOIN Players AS P2 ON P2.PlayerId = R.Player2Id 
) AS P 
    PIVOT 
    (
     MAX (Result) 
     FOR FirstName2 IN 
     (' + @Names + ') 
) AS pvt 
    ORDER BY pvt.FirstName1; 
    ' 

    EXEC(@SQL) 

    ------------------------------------------ 
    --Cleanup 
    ------------------------------------------ 

    DROP TABLE Results 
    DROP TABLE Players 
    DROP TABLE Leagues 
+0

что помогает, спасибо – simon1230756

+1

Нет проблем. Я уверен, как и многие другие на этой странице. Мне просто нравится решать такие проблемы. –

0

Это сложно, потому что каждый игрок может либо быть player1 или player2 в таблице результатов.

Этот подход может работать:

--First, make a list of each player and their score against their opponent 
WITH res (pID, score, opponentID) AS (
    SELECT res.player1id [pID], res.player1Result [score], res.player2id [opponent] 
    FROM results res 
    UNION 
    SELECT res2.player2id [pID], res2.player2Result [score], res2.player1id [opponent] 
    FROM results res2 
) 

--Then select one row for each player with all of their scores. 
SELECT p.FirstName, 
    res1.score [1], 
    res2.score [2], 
    res3.score [3], 
    res4.score [4], 
    res5.score [5] 
FROM Players p 
    LEFT OUTER JOIN res res1 ON p.playerid = res1.pID and res1.opponentID = 1 
    LEFT OUTER JOIN res res2 ON p.playerid = res2.pID and res2.opponentID = 2 
    LEFT OUTER JOIN res res3 ON p.playerid = res3.pID and res3.opponentID = 3 
    LEFT OUTER JOIN res res4 ON p.playerid = res4.pID and res4.opponentID = 4 
    LEFT OUTER JOIN res res5 ON p.playerid = res5.pID and res5.opponentID = 5 

Недостатком этого подхода является то, что вам может понадобиться, чтобы добавить или удалить код, если ваши лиги имеют больше или меньше игроков. Если вам нужно, чтобы он был динамичным, вы могли бы попробовать динамический PIVOT, что бы добавить к сложности.

+0

Я добавил ответ PIVOT на этот вопрос. –

Смежные вопросы