0

私の問題の簡略版。私は2つのテーブルを持っています:

スコア:

id  code_id score
1   11     100
2   12     20
3   13     40
4   14     70
5   15     90
6   16     10
7   17     30
8   18     50

コード:

id   code
11   
12
13
14
15
16    BBB
17    BBB
18    BBB

Codes テーブルに関連付けられたコードを持たない Scores テーブルのすべての行と、Codes テーブルに同一のコードを持つ行の最高スコアのみを返す Mysql SELECT クエリを作成する必要があります。

必要な出力を以下に示します。スコア ID の 1 ~ 5 は関連付けられたコードがないため存在しますが、BBB コードを持つすべてのスコアの最高値であるため、ID 8 のみが選択されます。

id  code_id score
1   11     100
2   12     20
3   13     40
4   14     70
5   15     90
8   18     50

それが理にかなっていることを願っています。これは簡単だと思っていましたが、戸惑いました。[greatest-n-per-group] のタグ付きの質問をチェックアウトしましたが、ほとんどの場合、GROUP BY とサブセレクトを実行するときに 1 つのテーブルしか参照していないようで、役に立ちませんでした。

どうもありがとう。

4

2 に答える 2

2

あなたの要件に何か欠けているかもしれませんが、2 つのクエリ間で UNION ALL を使用する方が簡単かもしれません。

nullテーブル内のコードを持つ行を取得するには、codes次を使用できます。

select s.id, s.code_id, s.score
from scores s
where exists (select id
              from codes c
              where s.code_id = c.id
                and c.code is null)

次に、max(score)for eachを取得するにはcode、次を使用できます。

select s.id, s.code_id, s.score
from scores s
inner join codes c
  on s.code_id = c.id
inner join
(
  select c.code, max(s.score) score
  from scores s
  inner join codes c
    on s.code_id = c.id
  where c.code is not null
  group by c.code
) m
  on c.code = m.code
  and s.score = m.score;

最後に、UNION ALL を使用して 2 つのクエリを組み合わせることができます。

select s.id, s.code_id, s.score
from scores s
where exists (select id
              from codes c
              where s.code_id = c.id
                and c.code is null)
union all
select s.id, s.code_id, s.score
from scores s
inner join codes c
  on s.code_id = c.id
inner join
(
  select c.code, max(s.score) score
  from scores s
  inner join codes c
    on s.code_id = c.id
  where c.code is not null
  group by c.code
) m
  on c.code = m.code
  and s.score = m.score
  group by c.code //To remove duplicates where the code and the score are equal

SQL Fiddle with Demoを参照してください。

code値が空の文字列であり、 ではない場合は補足として編集し、null使用するコードを変更できます''( demoを参照)。

于 2013-05-23T17:23:31.523 に答える
1

これを試して:

select s.*
from scores s join
     (select coalesce(code, cast(id as varchar(32))) as codeid, max(id) as id
      from codes c
      group by  coalesce(code, cast(id as varchar(32)))
     ) c
     on s.code_id = c.id;

コード テーブルを要約して、コードごとの最大 ID と、コードが NULL である各 ID の単一行を取得するという考え方です。

以下に結果を示します (申し訳ありませんが、これは SQL Server の場合ですが、コードは非常に似ています)。

declare @scores table (id int identity(1, 1), code_id int, score int);

insert into @scores(code_id, score)
    select 11, 100 union all
    select 12, 20 union all
    select 13, 40 union all
    select 14, 70 union all
    select 15, 90 union all
    select 16, 30 union all
    select 17, 30 union all
    select 18, 50;

declare @codes table (id int, code varchar(3));

insert into @codes(id, code)
    select 11, NULL union all
    select 12, NULL union all
    select 13, NULL union all
    select 14, NULL union all
    select 15, NULL union all
    select 16, 'BBB' union all
    select 17, 'BBB' union all
    select 18, 'BBB';   

select s.*
from @scores s join
     (select coalesce(code, cast(id as varchar(32))) as codeid, max(id) as id
      from @codes c
      group by  coalesce(code, cast(id as varchar(32)))
     ) c
     on s.code_id = c.id
于 2013-05-23T17:27:37.223 に答える