2016-04-29 16 views
1

次のようなデータを持つテーブルがあります。 「試み」の列は第2、第3、第4フィールドがテキストデータ型のときに最大値を選択する方法

entryid User Attempt 
1  1  First 
2  1  Second 
1  2  First 
2  2  Second 
3  2  Fourth 
4  2  First 

ユーザー2の場合に見ることができるように私は必要な出力があっても、

UsrID Attempt 
1  Second 
2  Fourth 

以下のようであるようなテキストエントリを持っていますユーザーの最新のエントリは 'First'です。彼は 'Fourth'のエントリを持っているので、Fourthを出力する必要があります。どうすれば達成できますか?

現在、EXISTS &が存在しないエントリをユーザが持っているかどうかを確認するために4つのクエリを使用しています。私はその結果をUNIONを使って結合します。また、CASE WHENを使用して各ステータスに数値を割り当て、その新しいフィールドの最大値を取ることも検討しています。誰かがより良い解決策を持っていますか?

+1

ここでMySQLまたはMS SQL Serverを使用していますか? (関連していない製品にはタグを付けないでください) – jarlh

+0

あなたが説明したことに基づいて、なぜ1のUsrIDが「Second」の試みを返すのでしょうか? –

+0

@jarlh mysqlタグを削除しました。それが推奨されたので追加しました。 – AntonyP

答えて

3

あなたはできないと思います。あなたのテーブルに

ストア整数の外部キー:

UsrID FkAttemptId 
1  2 
2  4 

とで別のテーブルを作成するには、参加する:あなたは追加の説明や他の言語のような多くの可能性を作ることができtahtで

AttemptId AttemptTitle 
1   First 
2   Second 
3   Third 
4   Fourth 

..

AttemptId AttemptTitle AttemptDescription AttemptFR ... 
1   First   Bla bla...   Premier 
2   Second   Bli bli...   Second 
3   Third   ... 
4   Fourth 
+0

これはいいですね。あるいは、英字表現を数字に変換してソートして照会で使用する関数を書くこともできます。あなたは[この記事で]いくつかの助けを見つけるかもしれない(http://stackoverflow.com/questions/8432527/convert-number-to-words-first-second-third-and-so-on) – dotNET

+0

はい、それはもっと簡単に。しかし、私はテーブルを編集することはできません。私は利用可能なデータで作業する必要があります。 – AntonyP

+0

これらのソリューションのいずれかでテーブルを編集*する必要はありません。 @ Melomanのソリューションでは、テーブルを作成する必要があります。私の提案では、*関数*を作成する必要があります。 – dotNET

3

ROW_NUMBERとでレコードをランク​​付けします。表現:

select eid, usrid 
from 
(
    select eid, usrid, 
    row_number() over 
    (
     partition by usrid 
     order by 
     case when attempt = 'First' then 1 
      when attempt = 'Second' then 2 
      when attempt = 'Third' then 3 
      when attempt = 'Fourth' then 4 
      else 5 
     end desc 
    ) as rn 
    from mytable 
) ranked 
where rn = 1; 
1

あなたはcasejoinを使用して、クエリで値を割り当てることによってこれを行うことができます。

select t.* 
from (select t.*, 
      row_number() over (partition by user order by n.num desc) as seqnum 
     from t join 
      (values ('First', 1), ('Second', 2), ('Third', 3), ('Fourth', 4) 
      ) n(val, num) 
      on t.attempt = n.val 
    ) t 
where seqnum = 1; 

は、私が参照テーブルを使用してデータを正規化することは、より理にかなっていることを他のコメントに同意します。しかし、時には、特定のフォーマットのデータに悩まされており、それに対処しなければならない場合もあります。この答えはその状況を解決します。

0

あなたはその後、あなたが行う必要があり、列の試み

Select X.USER_ID,T.ATTEMPT from (
    Select MYTABLE.USER_ID,MAX(TAB_ATTEMPTS.N) AS POSITION FROM 
    MYTABLE (NOLOCK) 
    JOIN 
    TAB_ATTEMPTS (NOLOCK) ON MYTABLE.ATTEMPT=TAB_ATTEMPTS.ATTEMPT 
    GROUP BY MYTABLE.USER_ID 
) as X 
JOIN TAB_ATTEMPTS T ON X.POSITION=T.N 

上の2つのテーブルを結合しているものと持ってテーブルに参加するために持っている

TAB_ATTEMPTS 

N Attempt 
1 first 
2 second 
3 third 
4 fourth 

のようなテーブルを構築する必要が作品。

0

"NumericAttempt"列のビューを作成し、その列のビューを照会します。

 
CREATE VIEW [viewOutput] 
AS 
SELECT 
entryid, 
User, 
Attempt, 
CASE Attempt 
    WHEN 'Fisrt' THEN 1 
    WHEN 'Second' THEN 2 
    WHEN 'Third' THEN 3 
    WHEN 'Fourth' THEN 4 
    WHEN 'Fifth' THEN 5 
    ELSE 999 
END as AttemptNumeric 
FROM TableName 

0

か...あなたは、第二の参加せずに好みなら...

Select X.USER_ID, 
     X.POSITION, 
     (select T.ATTEMPS FROM TAB_ATTEMPTS T where T.N=X.POSITION) AS ATTEMPT 
FROM 
(Select MYTABLE.USER_ID,MAX(TAB_ATTEMPTS.N) AS POSITION 
FROM 
MYTABLE (NOLOCK) 
JOIN 
TAB_ATTEMPTS (NOLOCK) ON MYTABLE.ATTEMPT=TAB_ATTEMPTS.ATTEMPT 
GROUP BY MYTABLE.USER_ID) as X 
+0

それを読む前に私の最初の答えを見てください... –

0

別のアプローチ:tattemptはあなたのテーブルの名前です

SELECT a.UsrID, a.Attempt 
FROM (SELECT * FROM tattempt a 
     JOIN (SELECT 1 AS id, 'First' AS value FROM dual 
      UNION 
      SELECT 2, 'Second' FROM dual 
      UNION 
      SELECT 3, 'Third' FROM dual 
      UNION 
      SELECT 4, 'Fourth' FROM dual) v 
      ON (a.Attempt = v.value) 
     ORDER BY v.id DESC) a 
GROUP BY a.UsrID; 

関連する問題