Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql SQL或子句优先级_Mysql_Sql - Fatal编程技术网

Mysql SQL或子句优先级

Mysql SQL或子句优先级,mysql,sql,Mysql,Sql,我有一个用户奖励表,可以是各种不同的类型 例如,以下是资格ID 94的记录: 如您所见,共有2个用户,一个用户有“平均”、“最小”、“最大”和“最终”奖励类型的记录,另一个用户有相同但没有“最终”奖励 我想要的是每个用户只获得1行。如果他们有一个“最终”类型的奖项,我想要那个,否则我想要一个“平均”的,我根本不想要“最小”或“最大” 因此,作为一个示例,以下是仅包含一个简单IN子句的查询: 基于此,我想要的结果是,对于用户34562,我想要有“最终”奖励的行,对于用户6256,我想要有“平均

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

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

如您所见,共有2个用户,一个用户有“平均”、“最小”、“最大”和“最终”奖励类型的记录,另一个用户有相同但没有“最终”奖励

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

因此,作为一个示例,以下是仅包含一个简单IN子句的查询:

基于此,我想要的结果是,对于用户34562,我想要有“最终”奖励的行,对于用户6256,我想要有“平均”奖励的行,因为他们没有“最终”记录

我相信这应该相当简单,但我今天早上失败得很惨

我想我应该能够选择最终的记录,然后做一个联盟所有,但我似乎无法在我的头脑中解决它。谁能给我指出正确的方向吗

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


谢谢。

您可以使用更具可伸缩性的
MySQL用户定义变量来完成这项工作

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 

这是一个纯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

此查询采用了一种技巧,即根据
final
average
是否存在,为每个
qualid
组聚合一个总和。我为
final
指定了
100
,为
average
指定了
10
,为两者都指定了
1
。这允许我们为每个组分配一个
类型。

一个简单的方法是检查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')

您可以在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

听说我们已经按类型按字符进行了排序,如果有其他文本符合我们的要求,那么只需添加大小写并根据该字段进行排序。

执行分组,使用大小写表达式进行条件聚合。能否快速测试我的查询,看看它是否有效。如果没有,我将删除它。这不是与其他数据库引擎不兼容吗?我们在这里使用MySQL,但该软件支持PostgreSQL、SQL Server等。。。同样,一些使用它的地方不会在MySQL上。然后你可以尝试其他的QueryEah,也许@Timbiegeleisentanks,这似乎是最简单的方法。我之前尝试过这个,但似乎无法正确地得到not exists查询。顺便说一句,你有一个打字错误,你把“not exists”改为“not exists”,以防你想为未来的观众更改它。嗨,不,它似乎不太正确,我现在已经接受了另一个人的答案,所以不用担心it@ConnWarwicker很抱歉我有个打字错误,现在可以了。
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