SQL OR子句优先级

时间:2016-09-22 09:47:17

标签: mysql sql

我有一个包含用户奖励的表格,可以是各种不同的类型。

例如,以下是资格ID 94的记录:

enter image description here

正如您所看到的,有2个用户,其中一个有“平均”,“最小”,“最大”和“最终”等奖项类型的记录,另一个具有相同但没有“最终”奖励。

我想要的是每个用户只能获得1行。如果他们有“最终”类型的奖励,我想要那个,否则我想要“平均”,我根本不想要“min”或“max”。

举个例子,这里的查询只有一个简单的IN子句:

enter image description here

基于此,我想要的结果是用户34562我想要具有“最终”奖项的行,而对于用户6256我希望该行获得“平均”奖励,因为他们不喜欢没有“最终”记录。

我确信这应该相当简单,但我今天早上失败了。

我想我应该能够选择最终的记录,然后做一个UNION ALL,但我似乎无法解决这个问题。有人能指出我正确的方向吗?

我应该指出,虽然这对我来说是MySQL,但它需要与其他数据库平台兼容。

感谢。

4 个答案:

答案 0 :(得分:2)

一种简单的方法是检查where子句中是否存在平均条目:

SELECT * FROM Table t
WHERE qualid = 94
and (type = 'average' AND
    not exists(SELECT * FROM Table t2
        WHERE t.qualid=t2.qualid AND t.userid=t2.userid AND type = 'final') 
    OR type = 'final')

答案 1 :(得分:0)

您可以使用更具可扩展性的MySQL user defined variables来完成此任务。

SELECT 
t.*
FROM 
(
    SELECT 
    *,
    IF(@sameUser = userid, @rn := @rn + 1,
        IF(@sameUser := userid, @rn := 1,@rn := 1)
    ) AS row_number
    FROM moodle.mdl_bcgt_user_qual_awards 
    CROSS JOIN (SELECT @sameUser := -1, @rn := 1) AS var
    WHERE qualid = 94
    AND type IN ('final','average')
    ORDER BY userid, 
        CASE WHEN type = 'final' THEN 0 ELSE 1 END 
) AS t
WHERE t.row_number <= 1
ORDER BY t.userid 

修改

使用NOT EXISTS&amp; UNION ALL

SELECT 
 *
FROM your_table 
WHERE qualid = 94
AND type = 'final'

UNION ALL 

SELECT 
 *
FROM your_table A
WHERE qualid = 94
AND type = 'average'
AND NOT EXISTS (
 SELECT 1 FROM your_table B WHERE A.qualid = B.qualid AND  B.userid = A.userid AND B.type = 'final'
)

答案 2 :(得分:0)

这是一个纯MySQL解决方案,在大多数RDBMS中通常也应符合ANSI标准:

SELECT t1.*
FROM yourTable t1
INNER JOIN
(
    SELECT qualid,
           CASE WHEN MAX(CASE WHEN type = 'final' THEN 100
                              WHEN type = 'average' THEN 10
                              ELSE 1
                         END) = 100 THEN 'final'
                WHEN MAX(CASE WHEN type = 'final' THEN 100
                              WHEN type = 'average' THEN 10
                              ELSE 1
                         END) = 10 THEN 'average'
                ELSE NULL
           END AS type
    FROM yourTable
    GROUP BY qualid
) t2
    ON t1.qualid = t2.qualid AND
       t1.type   = t2.type

此查询采用了一种技巧,即根据qualidfinal或两者都不存在来汇总每个average组的总和。我为100分配final,为10分配average,为1分配type。这允许我们为每个组分配ruby

答案 3 :(得分:0)

您可以尝试使用sql Server

Select * from (
    SELECT *,ROW_NUMBER() over(PARTITION  BY type ORDER BY type) rowNo
    FROM mdl_bcgt_user_qual_awards
    WHERE qualid = 94 
    AND type in ('final','average')
    Order By type
) as t
Where rowNo=1

听到我们已经完成了按类型划分的字符符合我们的要求,如果有任何其他文本,那么只需在该字段的基础上添加大小写和排序。