SQL:Order By,Substring,Union

时间:2016-04-27 00:30:34

标签: sql sql-order-by union

我希望通过'版本'的前8个字符的子字符串来排序以下查询的结果。数。我理解SUBSTRING(),所以不要打扰我。我的问题是试图将ORDER BY放在UNION上。

更新:我需要按版本的顺序返回数据,但仍然在具有相同GUID的其他行旁边排序。

当前查询是这样的,但版本是随机排列的。

/**** PLAYER MATCHUPS TWO  ***/    
SELECT e.[GUID], e.[KEY], e.[VALUE]    
FROM db e INNER JOIN 
    (SELECT[GUID] FROM db
    WHERE[Key] = 'Session.Type' and[Value] = 'EndMatchTypA') g 
ON e.[GUID] = g.[GUID] 
WHERE [KEY] IN('CharacterID', 
            'OpponentID', 
            'Version')
UNION ALL

/**** PLAYER MATCHUPS ONE  ***/
SELECT e.[GUID], e.[KEY], e.[VALUE] 
FROM db e INNER JOIN 
    (SELECT[GUID] FROM db
    WHERE[Key] = 'Session.Type' and [Value] = 'EndMatchTypeB') g 
ON e.[GUID] = g.[GUID] 
WHERE[KEY] IN('CharacterID', 
        'OpponentID',
        'Version')

这就是目前数据的返回方式。

GUID        Key             Value
-------------------------------------------
1313-2212   Version         3.0.4.0_x64_!#
1313-2212   CharacterID     3
1313-2212   OpponentID      5
4321-1567   Version         1.0.0.0_x64_!#
4321-1567   CharacterID     11
4321-1567   OpponentID      2

4 个答案:

答案 0 :(得分:2)

您可以使用SELECT

包装整个查询,然后ORDER BY
SELECT t.[GUID], t.[KEY], t.[VALUE]
FROM
(
    SELECT e.[GUID], e.[KEY], e.[VALUE]    
    FROM db e INNER JOIN 
        (SELECT[GUID] FROM db
        WHERE[Key] = 'Session.Type' and[Value] = 'EndMatchTypA') g 
    ON e.[GUID] = g.[GUID] 
    WHERE [KEY] IN('CharacterID', 
                'OpponentID', 
                'appVer')
    UNION ALL
    SELECT e.[GUID], e.[KEY], e.[VALUE] 
    FROM db e INNER JOIN 
        (SELECT[GUID] FROM db
        WHERE[Key] = 'Session.Type' and [Value] = 'EndMatchTypeB') g 
    ON e.[GUID] = g.[GUID] 
    WHERE[KEY] IN('CharacterID', 
            'OpponentID',
            'appVer')
) t
ORDER BY SUBSTRING(t.[VALUE], 1, 8)

注意:我测试了订购字符串版本号,数字顺序似乎保持不变。但是,您应该知道,如果您的版本号长度应该更改,这可能是一个问题。例如,如果版本可能变成两位数,这将打破我给出的ORDER BY(以及其他答案给出的)。

答案 1 :(得分:2)

您需要对JOIN表执行另一个db,以获得每个Version排序的[KEY]

SELECT 
    e.[GUID], e.[KEY], e.[VALUE] 
FROM db e 
INNER JOIN db g 
    ON  e.[GUID] = g.[GUID] 
        AND g.[Key] = 'Session.Type'
        AND g.[Value] IN ('EndMatchTypeA', 'EndMatchTypeB')
INNER JOIN (
    SELECT [GUID], [KEY], [VALUE]
    FROM db
    WHERE
        [KEY] = 'Version'
)v
    ON e.[GUID] = v.[GUID]
WHERE 
    e.[KEY] IN ('CharacterID', 'OpponentID', 'Version')
ORDER BY 
    SUBSTRING(v.[VALUE], 1, 8);

您也可以使用CROSS APPLY

SELECT 
    e.[GUID], e.[KEY], e.[VALUE] 
FROM db e 
INNER JOIN db g 
    ON  e.[GUID] = g.[GUID] 
        AND g.[Key] = 'Session.Type'
        AND g.[Value] IN ('EndMatchTypeA', 'EndMatchTypeB')
CROSS APPLY (
    SELECT [GUID], [KEY], [VALUE]
    FROM db
    WHERE
        [KEY] = 'Version'
        AND [GUID] = e.[GUID]
)v
WHERE 
    e.[KEY] IN ('CharacterID', 'OpponentID', 'Version')
ORDER BY 
    SUBSTRING(v.[VALUE], 1, 8);

向Gordon致信,以摆脱UNION ALL

答案 2 :(得分:1)

查询可以简化如下。使用substring获取value的前8个字符,并将.个字符替换为空字符,以便可以整数排序。

SELECT e.[GUID], e.[KEY], e.[VALUE] 
FROM db e 
INNER JOIN 
(SELECT[GUID] FROM db
 WHERE [Key] = 'Session.Type' and [Value] = 'EndMatchTypeA') ga
ON e.[GUID] = ga.[GUID] 
INNER JOIN 
(SELECT[GUID] FROM db
 WHERE [Key] = 'Session.Type' and [Value] = 'EndMatchTypeB') gb
ON e.[GUID] = gb.[GUID] 
WHERE e.[KEY] IN ('CharacterID','OpponentID','appVer')
ORDER BY cast(replace(substring(e.[VALUE],1,8),'.','') as int)

如果您想将order byunion一起使用,请在order by查询末尾使用union

select col1,col2 from sometable --where conditions
union all
select col1,col2 from sometable1 --where conditions
order by col1,col2

答案 3 :(得分:1)

首先,我不明白为什么你需要union all

SELECT e.[GUID], e.[KEY], e.[VALUE] 
FROM db e INNER JOIN
     db g 
     ON e.[GUID] = g.[GUID] AND 
        g.[Key] = 'Session.Type' AND
        g.[Value] IN ('EndMatchTypeA', 'EndMatchTypeB') 
WHERE e.[KEY] IN ('CharacterID', 'OpponentID', 'Version')
ORDER BY SUBSTRING(e.[VALUE], 1, 8);

然后,我可以将其更改为EXISTS

SELECT e.[GUID], e.[KEY], e.[VALUE] 
FROM db e 
WHERE e.[KEY] IN ('CharacterID', 'OpponentID', 'Version') AND
      EXISTS (SELECT 1
              FROM db g 
              WHERE e.[GUID] = g.[GUID] AND 
                    g.[Key] = 'Session.Type' AND
                    g.[Value] IN ('EndMatchTypeA', 'EndMatchTypeB')
             )
ORDER BY SUBSTRING(e.[VALUE], 1, 8);

我认为这最好地表达了查询的意图。并且,它可以防止重复项g具有两个值。而且,它可能使优化器更容易利用适当的索引。