postgresql中的递归函数

时间:2017-01-06 23:20:43

标签: sql postgresql

我有这张桌子:

CREATE TABLE players
(
    winner            CHARACTER VARYING(50) NOT NULL ,
    successor              CHARACTER VARYING(50) NOT NULL ,
    data           NUMERIC(6,2) NOT NULL ,
    CONSTRAINT pk_win_succ PRIMARY KEY (winner, successor)
);

数据:

  INSERT INTO players VALUES
  ('Helen','Sharon',12),
  ('Claudia','Steffi',35),
  ('Sharon','Penny',5),
  ('Meg','Claudia',21),
  ('Penny','Meg',3)
  ('Steffi','Helen',230);

我需要做的是一个SQL查询,它为玩家提供了不同的可能组合。

如果我选择玩家Sharon作为首发,玩家Meg作为最终玩家,则查询结果应为:

Initial | Final | List of winners | Total Data | Number of Winners |
Sharon | Meg | Sharon - Penny - Meg | 8 | 3

如果我选择玩家Claudia作为首发玩家并选择Sharon作为最终玩家,则查询结果应为:

Initial | Final | List of winners | Total Data | Number of Winners |
Claudia | Sharon | Claudia - Steffi - Helen - Sharon | 277 | 4

谢谢!

1 个答案:

答案 0 :(得分:0)

可以使用递归查询构建从Sharon到Meg的链:

Sharon;Penny;5.00;t
Penny;Meg;3.00;f

结果:

 WITH RECURSIVE chain(winner, successor, data, active) AS (
   SELECT winner, successor, data, true
     FROM players
     WHERE winner = 'Sharon'
   UNION ALL
   SELECT p.winner, p.successor, p.data
         ,CASE WHEN p.successor = 'Meg' OR NOT c.active THEN false ELSE true END
     FROM players p
     JOIN chain c ON (p.winner = c.successor AND c.active)
 )
 SELECT 'Sharon' AS Initial
       ,'Meg' AS Final
       ,'Sharon - ' || string_agg(successor, ' - ') AS Winners
       ,sum(data) AS Total
       ,count(*) + 1 AS WinnerCount
   FROM chain

然后可以将结果集聚合成所需的格式:

PREPARE plan(text, text) AS

 WITH RECURSIVE chain(winner, successor, data, active) AS (
   SELECT winner, successor, data, true
     FROM players
     WHERE winner = $1
   UNION ALL
   SELECT p.winner, p.successor, p.data
         ,CASE WHEN p.successor = $2 OR NOT c.active THEN false ELSE true END
     FROM players p
     JOIN chain c ON (p.winner = c.successor AND c.active)
)
SELECT $1 AS Initial
      ,$2 AS Final
      ,$1 || ' - ' || string_agg(successor, ' - ') AS Winners
      ,sum(data) AS Total
      ,count(*) + 1 AS WinnerCount
  FROM chain
;

EXECUTE plan('Sharon', 'Meg');

EXECUTE plan('Claudia', 'Sharon');

或参数化:

public class DisplayWebView extends AppCompatActivity {

    WebView webview;
    EditText link, date;
    Button insert;
    String[] receivedLink;
    ListView list;
    List<Model> ls_data;
    CustomAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_webview);

        Intent intent = new Intent(DisplayWebView.this, MyBroadcastReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(DisplayWebView.this, 234324243, intent, 0);
        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()
                + (5 * 10), pendingIntent);
    }
}