2017-11-14 12 views
1

最小値に問題があります。下の表では、d1、d2、d3の値が最小値です。 SQL min()関数またはleast()関数を使用すると、結果は常にleft side first(おそらく私は間違っている)という意味のd1列を意味します。最小値またはカラムを無作為に設定する最小値が同じ場合

私の質問です:least value or least columnをd1、d2、またはd3の中からランダムに設定する可能性はありますか?私はここで言いたいのですが、実行時間ごとに、値が同じ場合は最小列が変更されます。

formal

id date     name d1 d2 d3 d4 least_value  least_column 
1 2017-02-10T09:00:00Z bimal 1 1 1 4 1    d1 
select f.*, 
     (case ff.least_column 
      when 'd1' then d1 
      when 'd2' then d2 
      when 'd3' then d3 
      when 'd4' then d4 
     end) as least_value, 
     ff.least_column 
from formal f cross join 
    (select least(d1, d2, d3, d4) as least_value, 
      (case least(d1, d2, d3, d4) 
        when d1 then 'd1' 
        when d2 then 'd2' 
        when d3 then 'd3' 
        when d4 then 'd4' 
       end) as least_column 
     from formal 
    ) ff; 

SQL Fidle here

+0

を参照してください。ここで何をしようとしていますか? –

+0

'd2'または' d3'カラムを 'd1'カラムではなく' least_column'に設定したいと思います。設定することは可能ですか? –

+0

ケース式の条件内のフィールドの順序は、どのフィールド名が最小値として返されるかを決定します。ケース内のフィールドの順序がランダム化されているsqlを動的に生成できる場合は、受け取ったフィールド名を出力としてランダム化できます。 – Shadow

答えて

2

あなたがランダム化する能力を制限する小さな行構造に依存しています。私は、データを "unpivot"してより多くの行を生成し、よりランダムな結果を得ることをお勧めします。小文字の結果セット/テーブルでは大丈夫ですが、大きなセットでは問題ありません。あなたはこのSQL Fiddleを訪問し、任意の "ランダム" を参照して実行]をクリックする必要があります

CREATE TABLE formal 
    (`id` int, `date` datetime, `name` varchar(5), `d1` int, `d2` int, `d3` int, `d4` int) 
; 

INSERT INTO formal 
    (`id`, `date`, `name`, `d1`, `d2`, `d3`, `d4`) 
VALUES 
    (1, '2017-02-10 09:00:00', 'bimal', 1, 1, 1, 1); 

クエリ1

select 
* 
from (
     select id, date, name, d1 colvalue, 'd1' colsource from formal union all 
     select id, date, name, d2   , 'd2'   from formal union all 
     select id, date, name, d3   , 'd3'   from formal union all 
     select id, date, name, d4   , 'd4'   from formal 
    ) p 
inner join (
     select id, least(d1, d2, d3, d4) as least_value from formal 
    ) lv on p.id = lv.id 
where colvalue = least_value # correction here 
order by rand() 
limit 1 

Results

| id |     date | name | colvalue | colsource | id | least_value | 
|----|----------------------|-------|----------|-----------|----|-------------| 
| 1 | 2017-02-10T09:00:00Z | bimal |  1 |  d2 | 1 |   1 | 

は、複数行の結果については、IDごとに1:

| id |     date | name | colvalue | colsource | least_value | RowNumber | @prev := p.id | 
|----|----------------------|-------|----------|-----------|-------------|-----------|---------------| 
| 3 | 2017-02-10T09:00:00Z | suman |  1 |  d3 |   1 |   1 |    3 | 
| 1 | 2017-02-10T09:00:00Z | bimal |  1 |  d1 |   1 |   1 |    1 | 
| 2 | 2017-02-10T09:00:00Z | amal |  1 |  d2 |   1 |   1 |    2 | 

select 
    * 
from (
     select 
      p.* 
      , lv.least_value 
      , @row_num :=IF(@prev = p.id, @row_num + 1, 1)AS RowNumber 
      , @prev := p.id 
     from (
      select id, date, name, d1 colvalue, 'd1' colsource from formal union all 
      select id, date, name, d2   , 'd2'   from formal union all 
      select id, date, name, d3   , 'd3'   from formal union all 
      select id, date, name, d4   , 'd4'   from formal 
     ) p 
     inner join (
       select id, least(d1, d2, d3, d4) as least_value from formal 
      ) lv on p.id = lv.id 
     cross join (
      select @row_num := 0, @prev := null 
     ) vars 
     where colvalue = colvalue 
     order by p.id, rand() 
    ) d 
where rowNumber = 1 
; 

結果は、私はあなたの質問に従わないthis revised sqlfiddle

+0

あなたはSQLのフィドルをチェックしますか:http://sqlfiddle.com/#!9/628603/1。テーブルを「id」、「日付」、「名前」、「d1」、「d2」、「d3」、「d4」、「colvalue」、\t「colsource」、\t「id」、\t 'least_value'です。私はすべての名前を表示したい。 Plz help –

+0

あなたのコメントは意味をなさないので、あなたが私に利用可能にしたすべての情報項目はそのsqlfiddeにあります。あなたは "どのように私は各idのために1つの行を取得するのですか? (それは新しい質問です。imho)私は疲れすぎて止める必要があります。 –

+0

申し訳ありません。このフィドルでhttp://sqlfiddle.com/#!9/5d8a89/1すべての名前はどのように取得されますか?それは3行を意味します。私は3 idsまたは3行のIDを賢明に意味します。もう一度申し訳ありません。 –

関連する問題