2016-04-29 34 views
1

我有一個表格,其數據如下所示。在「嘗試」一欄有一個像第一,第二,第三和第四如何選擇文本字段中的最大值數據類型

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

我需要的輸出如下

UsrID Attempt 
1  Second 
2  Fourth 

正如你可以在用戶2的情況看,即使文本條目用戶的最新條目是'First',因爲他有'Fourth'的條目,所以我們需要輸出Fourth。我們如何實現它?

目前我使用四個查詢來檢查用戶是否有任何使用EXISTS & NOT EXISTS的條目。然後我使用UNION加入他們的結果。我也在考慮使用CASE WHEN分配每個狀態的數字,然後考慮新的字段的最大值。誰會有更好的解決方案?

+1

您在這裏使用MySQL或MS SQL Server嗎? (請勿標記不涉及的產品。) – jarlh

+0

根據您所解釋的內容,爲什麼'UsrID'爲1會返回'Second'嘗試? –

+0

@jarlh我已經刪除了mysql標籤。我補充說,因爲這是建議。 – AntonyP

回答

3

我認爲你不行。

商店整數外鍵到表:

UsrID FkAttemptId 
1  2 
2  4 

,並與另一個表聯接:

AttemptId AttemptTitle 
1   First 
2   Second 
3   Third 
4   Fourth 

隨着taht可以讓很多像附加說明或其他語言的可能性.. 。

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_NUMBERCASE表達:

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

你必須建立這樣的

TAB_ATTEMPTS 

N Attempt 
1 first 
2 second 
3 third 
4 fourth 

表。然後,你必須參加,你有一個在列嘗試

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 

這應該做連接兩個表的表工作。

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

另一種方法:

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; 

其中tattempt是你的表的名稱。

相關問題