2016-10-07 1 views
0

すべてのチケットがどのように見えるかを知っている90ボールビンゴゲームエンジンの場合、勝者チケットの最短パスを計算する必要があります与えられたゲームのために呼び出されました。90ボールビンゴ - 勝者チケットへの最短経路

各試合について、約1000枚のチケットを生成する予定で、「1行」、「2行」(1つのチケット、明らかに)と「フルチケット」という3つのコンテストが行​​われます。

パスは、特定のコンテストで勝者のチケットを得るために必要な番号として定義されています。

テーブルレイアウトは非常に単純です:

A ticket belongs to a game - it has three rows 
A ticket row belongs to a ticket - it has 5 fields 
A ticket row field belongs to a ticket row - it has one content field 

呼び出さ数字は、ゲームごとに登録されています。

チケット: ID game_id

ticket_row: ID TICKET_ID

ticket_row_field: ID ticket_row_id コンテンツ

called_number: game_id called_number

すべてのフィールドは整数型です。

コンテスト「1 row」と「full ticket」の最短パスを取得するのは簡単ですが、それぞれticket_row_idとticket_idでグループ化できます。いた(私はMySQLを使用してコンテスト「同じチケットの2行」のための最短経路を見つけるにはどうすればよい:

select 
    r.ticket_id, 
    count(content) path_distance, 
    group_concat(content order by content) path 
from 
    ticket t 
    inner join ticket_row r 
     on r.ticket_id = t.id 
    inner join ticket_row_field f 
     on f.ticket_row_id = r.id 
    left join called_number n 
     on n.game_id = t.game_id 
     and n.called_number = f.content 
where 
    n.called_number is null 
group by 
    ticket_row_id 
having 
    path_distance < 4 
order by 
    path_distance; 

私の問題がある:ここでは

は、私は1行のコンテストのためにそれを行う方法ですウィンドウ関数をサポートしていない)?

これをより専門的に説明すると、各チケットでは、フィールドの内容のうち、called_numberと一致しないものの合計を見つける必要があります。欠落したフィールドの数が少ないチケットが最初に来るようにチケットを注文する必要があります。

私はこのように見える結果を希望:

+-----------+---------------+------------+ 
| ticket_id | path_distance | path | 
+-----------+---------------+------------+ 
|  12 |    3 | 14,32,78 | 
+-----------+---------------+------------+ 
|   9 |    4 | 2,58,76,89 | 
+-----------+---------------+------------+ 
... etc 
+0

1行コンテストのソリューションでは、チケットがすでに完全な行を持っている場合でも、3回まですべてのチケットがリストされます。チケット12は、既にそれを獲得している場合は、1行のチャレンジに勝つために14,32,78の数字が必要です。それにもかかわらず、2行目(3回目のジョイントを2回追加し、 'r1.ticket_row_id Solarflare

+0

@solarflareこの例のクエリは、path_distanceが4より小さい行を返します。これは、1つのチケットから複数の行を返すことを意味していても、それは設計によるものです。しかし、私はあなたの提案された追加の結合がどのように見えるべきかを完全に理解しているのか分からない。例を教えてください。 – henrik242

+0

私は、次のことを意味しています:内部結合ticket_row r2 r.ticket_id = t.idとr1.ticket_row_id!= r.ticket_row_id内部結合ticket_row_field f2 on f2.ticket_row_id = r.id left join join_number n2 on n2.game_id = t.game_idとn2.called_number = f2.content'を入力し、条件を調整して選択します(たとえば、「distinct」を追加します)。あなたが(簡略化した)テーブル構造(あなたのqureyのフィールドを含む)といくつかのサンプルデータを提供すれば、私はそれを行うことができます。 – Solarflare

答えて

0

をfolllowingが移動するための方法であるように思わ: まず我々は

を理解し、実際の選択クエリを容易にするので、ビューのカップルを作成します

この最初のビューは、すでに完全に埋められている行を表します。つまり、5つの数値もすべて呼び出されたことを意味します。

create or replace view filled as 
select 
    r.ticket_id, f.ticket_row_id, 0 path_distance 
from 
    ticket_row_field f 
    inner join ticket_row r 
     on r.id = f.ticket_row_id 
    inner join ticket t 
     on t.id = r.ticket_id 
    inner join called_number n 
     on n.called_number = f.content 
group by ticket_row_id 
having count(*) = 5; 

他のビューは完全にその後、我々は彼らのパス(=欠番)を含め、我々は必要なチケットを、取得するには、次のSELECTクエリを使用し

create or replace view incomplete as 
     select 
      r.ticket_id, f.ticket_row_id, 
       coalesce(filled.path_distance, count(content)) path_distance, 
       case when 
        filled.path_distance is not null then 
        '' else 
        group_concat(content order by content) 
       end path 
     from 
      ticket t 
      inner join ticket_row r 
       on r.ticket_id = t.id 
      inner join ticket_row_field f 
       on f.ticket_row_id = r.id 
      left join called_number n 
       on n.game_id = t.game_id 
       and n.called_number = f.content 
      left join filled 
       on filled.ticket_row_id = f.ticket_row_id 
     where 
      n.called_number is null or filled.ticket_row_id is not null 
     group by 
      ticket_row_id; 

を満たさない行

を表し
select 
    r1.ticket_id, r1.path_distance + r2.path_distance distance_sum, concat(r1.path, ',', r2.path) path_combined 
from 
    incomplete r1 
     inner join incomplete r2 
      on r2.ticket_id = r1.ticket_id 
where 
    r2.ticket_row_id < r1.ticket_row_id 
order by 
    distance_sum 
limit 5; 
関連する問題