按特定值除外的组

时间:2011-12-22 23:39:13

标签: sql sqlite

我正在尝试创建一个(sqlite)查询,该查询将执行GROUP BY但不会对值为'unknown'的任何内容进行分组。例如,我有表:

id |   name  | parent_id | school_id |
 1 | john    |   1       |    1      |
 2 | john    |   1       |    1      |
 3 | john    |   1       |    1      |
 4 | nick    |   2       |    2      |
 5 | nick    |   2       |    2      |
 6 | nick    |   3       |    3      |
 7 | bob     |   4       |    4      |
 8 | unknown |   5       |    5      |
 9 | unknown |   5       |    5      |
 10| unknown |   5       |    5      |

使用'GROUP BY name,parent_id,school_id'进行正确查询我需要返回以下行:

id |   name  | parent_id | school_id |
 1 | john    |   1       |    1      |
 3 | nick    |   2       |    2      |
 4 | nick    |   3       |    3      |
 5 | bob     |   4       |    4      |
 6 | unknown |   5       |    5      |
 7 | unknown |   5       |    5      |
 8 | unknown |   5       |    5      |

非常感谢任何帮助。谢谢!

4 个答案:

答案 0 :(得分:8)

您不能轻易地使用一个语句执行此操作,但可以UNION两个语句的结果

  • GROUP所有的列表,但 unknown
  • 添加(UNION)所有unknown
  • 的列表

SQL声明

SELECT MIN(id), name, parent_id, school_id
FROM   YourTable
WHERE  name <> 'unknown'
GROUP BY
       name, parent_id, school_id
UNION ALL
SELECT id, name, parent_id, school_id
FROM   YourTable
WHERE  name = 'unknown'

请注意,我认为您在结果中发布了错误的unknown个ID

答案 1 :(得分:2)

作为单个查询...

SELECT
  MIN(id)            AS id,
  name,
  parent_id,
  school_id
FROM
  yourTable
GROUP BY
  CASE WHEN name = 'unknown' THEN id ELSE 0 END,
  name,
  parent_id,
  school_id

或者可能......

GROUP BY
  CASE WHEN name <> 'unknown' THEN name ELSE CAST(id AS VARCHAR(???)) END,
  parent_id,
  school_id

-- Where VARCHAR(???) is the data type of the `name` field.
-- Also assumes no value in `name` is the same as an id for an 'unknown' field

两者都避免使用UNION和解析表两次的开销,将其替换为稍微增加的复杂度GROUP BY

答案 2 :(得分:1)

SELECT  MIN(id), name, parent_id, school_id
  FROM  Table
WHERE   name <> 'unknown'
GROUP BY name, parent_id, school_id
UNION ALL
SELECT  id, name, parent_id, school_id
  FROM  Table
 WHERE  name = 'unknown'

答案 3 :(得分:1)

SELECT 
  MIN(id) AS id,
  IF(tmpname=id,"unknown",tmpname) AS name,
  parent_id,
  school_id
FROM (
  SELECT 
    id,parent_id,school_id
    IF(name="unknown",id,name) AS tmpname
  FROM <tablename>
) AS baseview
GROUP BY tmpname