2011-12-22 97 views
7

我試圖創建一個(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姓名,PARENT_ID,學校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  | 

任何幫助將不勝感激。謝謝!

+0

答案添加避免GROUP BY和解析表兩次的成本。 – MatBailie 2011-12-22 23:59:04

回答

7

你不能輕易做到這一點有一個說法,但你可以UNION兩個語句

  • GROUP所有unknown
  • 添加(UNION)的所有unknown的名單列表的結果

SQL Statement

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在你的結果

+0

絕對的輝煌! – Rahul 2011-12-22 23:43:22

+0

@Rahul - 印在牆上:) – 2011-12-22 23:47:38

+0

完美...謝謝! – Nick 2011-12-22 23:54:32

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' 
+0

+1看起來有點相同。 – 2011-12-22 23:57:51

+0

是啊...但我喜歡你的答案......你沒有解釋尼克如何去關於查詢:) – Akhil 2011-12-23 00:27:23

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 
+0

+1有趣,但你應該在parent_id&school_id上分組,你不能對我的知識檢查'tmpname = ID'在你的外部選擇。 – 2011-12-23 00:02:06

+0

應該tmpid tmpid相同的方式 - 對不起 – 2011-12-23 00:03:36

+1

@Lievent - 同意,需要將這兩個字段添加到GROUP BY,然後將第一個IF()塊中的'id'更改爲'MIN(id)'。我也明確地將整型轉換爲varchar(),以避免模糊,並嘗試將varchar()轉換爲整數。 [在兩個IF()塊中。] – MatBailie 2011-12-23 00:14:17

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

+0

+1 Afaik,這可以在SQL Server中工作,但SQLLite允許它嗎? – 2011-12-23 00:06:50

+0

@Lieven - 我不知道tbh,它需要測試。除語法差異之外,這不會根據ANSI SQL破壞任何內容。我希望它可以工作,這不是一個複雜的查詢... – MatBailie 2011-12-23 00:11:00

+0

不復雜,但不是立即想到的東西。雖然我不確定成本:UNION *可以*使用索引,而CASE是全表掃描。 OP將不得不比較執行計劃來驗證哪些功能性能最好。 – 2011-12-23 00:16:23

相關問題