2011-12-22 30 views
7

मैं एक (एसक्लाइट) क्वेरी बनाने की कोशिश कर रहा हूं जो ग्रुप BY करेगा, लेकिन 'अज्ञात' मान के साथ कुछ भी समूह नहीं करेगा। उदाहरण के लिए, मैं मेज है:कुछ मूल्य के अलावा समूह

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  | 
के साथ उचित क्वेरी के साथ

'द्वारा नाम, 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  | 

किसी भी मदद की बहुत सराहना की जाएगी। धन्यवाद!

+0

ग्रुप BY से बचने और तालिका को दो बार पार्स करने की लागत से जोड़ा गया उत्तर। – MatBailie

उत्तर

7

आप आसानी से एक बयान के साथ ऐसा नहीं कर सकते, लेकिन यदि आप दो कथन

  • GROUP सभी लेकिनunknown
  • जोड़ें (UNION) सभी unknown की सूची की सूची के परिणामों UNION कर सकते हैं

एसक्यूएल स्टेटमेंट

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' 

ध्यान दें कि मैं आप मान अपने परिणाम

+0

बिल्कुल शानदार !! – Rahul

+0

@Rahul - मुद्रित और दीवार पर तैयार :) –

+0

बिल्कुल सही ... धन्यवाद! – Nick

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 वही विचार ऐसा लगता है। –

+0

हाँ ... लेकिन मुझे आपका जवाब पसंद है ... आपने निक को समझाया कि क्वेरी के बारे में कैसे जाना है :) – Akhil

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 = आईडी 'आपके बाहरी चयन में। –

+0

tmpid के समान तरीके से tmpid होना चाहिए - क्षमा करें –

+1

@Lievent - सहमत, उन दो फ़ील्ड को GROUP BY में जोड़ने की आवश्यकता है, फिर पहले आईडी() ब्लॉक में 'आईडी' को 'MIN (id)' में बदलें। मैं स्पष्ट रूप से एक वर्चर() को पूर्णांक डालना चाहता था, ताकि अस्पष्टता से बचने के लिए और वर्चर() को पूर्णांक में डालने की कोशिश करने की संभावना हो। [दोनों IF() ब्लॉक में।] – MatBailie

2

किसी एक क्वेरी के रूप में में गलत unknown पहचान-पत्र पोस्ट किया है ...

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 

दोनों यूनियन से बचने और तालिका को दो बार पार्स करने के ऊपरी हिस्से से बचते हैं, इसे थोड़ी बढ़ी जटिलता GROUP BY के साथ बदल दिया जाता है।

+0

+1 अफैक, यह SQL सर्वर में काम करेगा लेकिन SQLLite इसे अनुमति देता है? –

+0

@Lieven - मुझे tbh नहीं पता, इसे परीक्षण की आवश्यकता होगी। सिंटैक्स विसंगतियों के अलावा, यह एएनएसआई एसक्यूएल के अनुसार कुछ भी नहीं तोड़ता है। मुझे उम्मीद है कि यह काम करता है, यह एक जटिल सवाल नहीं है ... – MatBailie

+0

जटिल नहीं है लेकिन कुछ ऐसा नहीं जो तुरंत दिमाग में आता है। हालांकि मुझे लागत के बारे में निश्चित नहीं है: यूनियन * इंडेक्स का उपयोग कर सकता है जबकि सीएएसई एक पूर्ण टेबल स्कैन है। सबसे अच्छा प्रदर्शन करने के लिए ओपी को निष्पादन योजनाओं की तुलना करना होगा। –

संबंधित मुद्दे