壁球联赛结果 - SQL查询

时间:2015-09-01 14:52:36

标签: sql tsql

我最近在我参加的壁球俱乐部接管了内部联赛。

我希望将这些内容放在网上供会员查看并根据需要添加结果

联盟结构遵循以下格式,有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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

这很棘手,因为每个玩家可以是Results表中的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,这会增加复杂性。