Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

Teams Drafting Players

Frank KulashMay 31 2019 — edited Jun 3 2019

Hi,

How can we model how sports teams draft new players, such that teams pick players one at a time, and once a team has picked a player, that player is unavailable to other teams?

Say we have these teams:

CREATE TABLE    team (team_name)    AS    -- team name is unique
SELECT  'Atletico'   FROM  dual  UNION ALL
SELECT  'Burnley'    FROM  dual  UNION ALL
SELECT  'Crystal'    FROM  dual  UNION ALL
SELECT  'Dortmund'   FROM  dual  UNION ALL
SELECT  'Everton'    FROM  dual;

and they can choose from these players:

CREATE TABLE    player  (player_name)    AS  -- player_name is unique
SELECT  'Mane'     FROM dual  UNION ALL
SELECT  'Neymar'   FROM dual  UNION ALL
SELECT  'Ronaldo'  FROM dual  UNION ALL
SELECT  'Silva'    FROM dual  UNION ALL
SELECT  'Weah'     FROM dual  UNION ALL
SELECT  'Xavi'     FROM dual  UNION ALL
SELECT  'Yorke'    FROM dual  UNION ALL
SELECT  'Zidane'   FROM dual;

The teams have rated various players as shown in the choice table; a higher rating means more desirable.

CREATE TABLE    choice (team_name, player_name, rating)    AS  -- combination of
SELECT  'Atletico', 'Mane',    90  FROM dual  UNION ALL        -- (team_name, player_name)
SELECT  'Atletico', 'Neymar',  80  FROM dual  UNION ALL        -- is unique; so is
SELECT  'Atletico', 'Ronaldo', 60  FROM dual  UNION ALL        -- (team_name, rating)
SELECT  'Burnley',  'Silva',   91  FROM dual  UNION ALL
SELECT  'Burnley',  'Weah',    71  FROM dual  UNION ALL
SELECT  'Burnley',  'Zidane',  51  FROM dual  UNION ALL
SELECT  'Crystal',  'Silva',   82  FROM dual  UNION ALL
SELECT  'Crystal',  'Weah',    72  FROM dual  UNION ALL
SELECT  'Crystal',  'Mane',    62  FROM dual  UNION ALL
SELECT  'Dortmund', 'Silva',   93  FROM dual  UNION ALL
SELECT  'Dortmund', 'Weah',    83  FROM dual  UNION ALL
SELECT  'Dortmund', 'Mane',    73  FROM dual  UNION ALL
SELECT  'Everton',  'Weah',    94  FROM dual  UNION ALL
SELECT  'Everton',  'Silva',   84  FROM dual  UNION ALL
SELECT  'Everton',  'Yorke',   74  FROM dual;

Let's say the teams pick in alphabetic order.

Atletico is first in alphabetic order, so Atleco picks the player they rated highest, i.e. Mane.

Burnley picks next.  It's top pick, Silva, hasn't been picked yet, so Burnley picks Silva.

Crystal picks next.  It's top pick, Mane, has already been picked, but their next choice, Weah, is still available, so Crystal picks Weah.

Dortmund picks next.  All the players Dortmund rated have already been picked, so Dortmund doesn't pick anyone.  (I know that's not how sports teams really operate.)

Everton picks next.  It's two highest-rated players have already been picked, so they have to settle for their third choice, Yorke.

So the results I want from this sample data are:

TEAM_NAME PLAYER_NAME

--------- ------------

Atletico  Mane

Burnley   Silva

Crystal   Weah

Dortmund

Everton   Yorke

What's a good way to get those results in Oracle SQL, without using PL/SQL?  I'm using Oracle 12.2, but I'd be interested in solutions from any version.

I found one way:

WITH    player_plus (player_name, player_letter)   AS

(

    SELECT  player_name

    ,       CHR (32 + ROW_NUMBER () OVER (ORDER BY player_name))

    FROM    player

)

,    team_plus (team_name, team_num, player_list)    AS

(

    SELECT    t.team_name

    ,         ROW_NUMBER () OVER (ORDER BY t.team_name)

    ,         LISTAGG (p.player_letter) WITHIN GROUP (ORDER BY c.rating DESC)

    FROM      team         t

    JOIN      choice       c  ON  c.team_name    = t.team_name

    JOIN      player_plus  p  ON  p.player_name  = c.player_name

    GROUP BY  t.team_name

)

,    recruit (team_name, team_num, player_letter, already_taken)  AS

(

    SELECT  team_name, team_num

    ,       SUBSTR (player_list, 1, 1)

    ,       SUBSTR (player_list, 1, 1)

    FROM    team_plus

    WHERE   team_num  = 1

UNION ALL

    SELECT  t2.team_name, t2.team_num

    ,       SUBSTR ( LTRIM (t2.player_list, r2.already_taken)

                   , 1

                   , 1

                   )

    ,       SUBSTR ( LTRIM (t2.player_list, r2.already_taken)

                   , 1

                   , 1

                   ) || r2.already_taken

    FROM    recruit    r2

    JOIN    team_plus  t2  ON  t2.team_num  = r2.team_num + 1

)

SELECT    rc.team_name

,         pp.player_name

FROM             recruit      rc

LEFT OUTER JOIN  player_plus  pp  ON   pp.player_letter  = rc.player_letter

ORDER BY  rc.team_name

;

which works for a small number of players, but I'm wondering if there's a better way that does not depend on the number of characters in my character set, or the maximum length of strings.

This post has been answered by chris227 on Jun 3 2019
Jump to Answer

Comments

AlokKumar
Hi,
dear let me explain what you really want?I go through to your question buy unable to get your point.if you really suffering from something let the doctor know what the problem is? otherwise you end up with nothing your hand.


thanks..
399843
Hi,
It basically means that neither of the two groups has been utilized yet. Here's what will tickle the situation: Invoke a log switch on the primary database, and then watch the status on standby; one of the logs should be in use, w/ status ACTIVE. The second one will remain UNASSIGNED - probably the equivalent of INACTIVE from the v$log view.
437185
Thanks for the reply Sophie. I did perform log switch at my primary site but the status of standby redo log files remained unassinged. I am pasting here the message in my Alert Log file may be that can help you to diagonose the problem.



ALTER DATABASE SET STANDBY DATABASE PROTECTED
Tue Jul 26 15:35:18 2005
Completed: ALTER DATABASE SET STANDBY DATABASE PROTECTED
Tue Jul 26 15:35:22 2005
ALTER DATABASE OPEN
Tue Jul 26 15:35:23 2005
LGWR: Primary database is in CLUSTER CONSISTENT mode
LGWR: Primary database is in MAXIMUM PROTECTION mode
LGWR: Destination LOG_ARCHIVE_DEST_1 is not serviced by LGWR
LNS0 started with pid=18
Tue Jul 26 15:35:28 2005
LGWR: Error 16086 verifying archivelog destination LOG_ARCHIVE_DEST_2
LGWR: Continuing...
Tue Jul 26 15:35:28 2005
Errors in file e:\oracle\admin\test\bdump\test_lgwr_1864.trc:
ORA-16086: standby database does not contain available standby log files

LGWR: Error 16086 disconnecting from destination LOG_ARCHIVE_DEST_2 standby host 'TESTstdb'
LGWR: Minimum of 1 applicable standby database required
Tue Jul 26 15:35:28 2005
Errors in file e:\oracle\admin\test\bdump\test_lgwr_1864.trc:
ORA-16072: a minimum of one standby database destination is required

LGWR: terminating instance due to error 16072
Instance terminated by LGWR, pid = 1864
399843
Ok, looks like a couple of initialization params may be misconfigured in your primary and/or standby sites. Particulary, log_archive_dest_1, log_archive_dest_2, log_archive_dest_state_2, and maybe a couple others, b/c your errors indicate that the primary database (I assume that was the alert log file from) doesn't know of your standby's archive log destination.
608015
hi

please try to run this Command and then open the primary database.

alter database set standby database to maximize performance;

alter database open;
1 - 5

Post Details

Added on May 31 2019
16 comments
977 views