2011-03-28 14 views
26

मैं कुछ सबक्विरी के साथ कुछ एसक्यूएल प्रश्न लिख रहा हूं और सबकुछ के अंदर और सबकुछ के परिणामस्वरूप तालिका के अंदर, हर जगह कई सारे जुड़ता हूं।स्वरूपण साफ़ और पठनीय एसक्यूएल प्रश्न

हम विचारों का उपयोग नहीं कर रहे हैं ताकि सवाल से बाहर हो।

इसे लिखने के बाद मैं इसे देख रहा हूं और अपने सिर को खरोंच कर रहा हूं कि यह क्या कर रहा है क्योंकि मैं इसका पालन नहीं कर सकता।

इस तरह की गड़बड़ी को साफ करने के प्रयास के लिए आप किस प्रकार का स्वरूपण उपयोग करते हैं? इंडेंट्स शायद?

+0

क्या प्लेटफ़ॉर्म? एसएसएमएस और MySQL वर्कबेंच के लिए प्लगइन हैं जो आपके लिए आपके SQL कोड को "सुंदर" बनाएंगे। –

+0

अच्छा सवाल। मुझे अभी तक एसक्यूएल के लिए एक दृढ़ स्वरूपण-नियम नहीं मिला है। –

+0

@ ब्रायन ड्रिस्कॉल, आप किस प्लगिंग को MySQL वर्कबेंच के लिए जानते हैं? – dcarneiro

उत्तर

17

बड़े प्रश्नों के साथ मैं WITH का उपयोग कर नामित परिणाम सेट पर बहुत निर्भर करता हूं। यह परिणाम सेट को पहले से परिभाषित करने की अनुमति देता है और यह मुख्य क्वेरी को सरल बनाता है। नामित परिणाम सेट क्वेरी प्लान को और अधिक कुशल बनाने में मदद कर सकते हैं जैसे कि उदा।पोस्टग्रेज़ एक अस्थायी तालिका में परिणाम सेट स्टोर करता है।

उदाहरण:

WITH 
    cubed_data AS (
    SELECT 
     dimension1_id, 
     dimension2_id, 
     dimension3_id, 
     measure_id, 
     SUM(value) value 
    FROM 
     source_data 
    GROUP BY 
     CUBE(dimension1, dimension2, dimension3), 
     measure 
), 
    dimension1_label AS(
    SELECT 
     dimension1_id, 
     dimension1_label 
    FROM 
     labels 
    WHERE 
     object = 'dimension1' 
), ... 
SELECT 
    * 
FROM 
    cubed_data 
    JOIN dimension1_label USING (dimension1_id) 
    JOIN dimension2_label USING (dimension2_id) 
    JOIN dimension3_label USING (dimension3_id) 
    JOIN measure_label USING (measure_id) 

उदाहरण एक सा काल्पनिक है, लेकिन मुझे आशा है कि यह इनलाइन सबक्वेरी की तुलना में स्पष्टता में वृद्धि को दर्शाता है। जब मैं ओलाप उपयोग के लिए डेटा तैयार कर रहा हूं तो नामित परिणाम सेट मेरे लिए बहुत मददगार रहे हैं। यदि आप रिकर्सिव क्वेरी बनाना चाहते हैं तो नामित परिणाम सेट भी आवश्यक हैं।

WITH एक हजार राय और कोई भी सही जवाब है, और मेरे पसंदीदा में से एक के साथ Postgres, ओरेकल और एसक्यूएल सर्वर

+0

कीवर्ड के साथ दिलचस्प है। निश्चित रूप से कोड को इतना क्लीनर बनाता है क्योंकि मैं केवल बाद की पंक्तियों में नाम के परिणाम को संदर्भित कर सकता हूं। – MxyL

3

आम तौर पर, लोगों को आरक्षित शब्द पर लाइनों को तोड़ने, और किसी भी उप प्रश्नों इंडेंट:

SELECT * 
FROM tablename 
WHERE value in 
    (SELECT * 
    FROM tablename2 
    WHERE condition) 
ORDER BY column 
4

टेबल उपनाम और सरल स्थिरता आप एक लंबे, लंबा रास्ता

क्या सभ्य लग रहा है मिल जाएगा लाइनों को तोड़ने है मुख्य कीवर्ड पर चुनें, जहां से, जहां (आदि ..)।

जॉइन ट्रिकियर हो सकता है, जुड़ने के चालू हिस्से को इंडेंट करने से सामने का महत्वपूर्ण हिस्सा सामने आता है।

जटिल स्तर पर तर्कसंगत अभिव्यक्ति (जोड़ों और कहां स्थितियां दोनों) तोड़ने से भी मदद मिलती है।

तार्किक ही (आदि सबक्वेरी, कोष्ठक खोलने,) बयान के स्तर

सभी कीवर्ड और मानक कार्यों कैपिटल में Indenting।

वास्तव में जटिल एसक्यूएल टिप्पणियों से दूर नहीं होगा - हालांकि आम तौर पर आप उन्हें एसक्यूएल स्क्रिप्ट्स में गतिशील एसक्यूएल नहीं पाते हैं।

संपादित करें उदाहरण:

SELECT a.name, SUM(b.tax) 
FROM db_prefix_registered_users a 
     INNER JOIN db_prefix_transactions b 
      ON a.id = b.user_id 
     LEFT JOIN db_countries 
      ON b.paid_from_country_id = c.id 
WHERE a.type IN (1, 2, 7) AND 
     b.date < (SELECT MAX(date) 
       FROM audit) AND 
     c.country = 'CH' 

तो, अंत में यह योग करने के लिए ऊपर - स्थिरता मायने रखती है सबसे।

2

इसे एक दृश्य में रखें ताकि विज़ुअलाइज़ करना आसान हो, हो सकता है कि दस्तावेज़ के हिस्से के रूप में स्क्रीनशॉट रखें। आपको दृश्य को सहेजने या किसी अन्य उद्देश्य के लिए इसका उपयोग करने की आवश्यकता नहीं है।

3

सामान्य रूप से, मैं फ़ॉर्मेटिंग नियमों का एक सरल पदानुक्रमित सेट का पालन करता हूं। असल में, SELECT, FROM, ORDER जैसे कीवर्ड सभी अपनी लाइन पर जाते हैं। प्रत्येक क्षेत्र (एक पुनरावर्ती फैशन में) अपनी पंक्ति में चला जाता है

SELECT 
    F.FIELD1, 
    F.FIELD2, 
    F.FIELD3 
FROM 
    FOO F 
WHERE 
    F.FIELD4 IN 
    (
     SELECT 
      B.BAR 
     FROM 
      BAR B 
     WHERE 
      B.TYPE = 4 
      AND B.OTHER = 7 
    ) 
3

मैं की तरह कुछ का उपयोग करना चाहते: निश्चित रूप से

SELECT col1, 
      col2, 
      ... 
FROM 
    MyTable as T1 
INNER JOIN 
    MyOtherTable as T2 
     ON t1.col1 = t2.col1 
     AND t1.col2 = t2.col2 
LEFT JOIN 
    ( 
     SELECT 1,2,3 
     FROM Someothertable 
     WHERE somestuff = someotherstuff 
    ) as T3 
    ON t1.field = t3.field 
2

Indenting लेकिन आप यह भी ऊपर टिप्पणी के साथ सबक्वेरी विभाजित कर सकते हैं, आप अपना उपनाम बनाना कुछ वास्तव में सार्थक नाम दें और निर्दिष्ट करें कि वे किस सबक्वायरी का उल्लेख करते हैं आंतरिक ग्राहक, बाहरी ग्राहक।

आम तालिका अभिव्यक्ति वास्तव में कुछ मामलों में सार्थक वर्गों में एक प्रश्न तोड़ने में मदद कर सकती है।

2

एक सदियों पुरानी प्रश्न के वर्तमान संस्करण पर कम से कम काम करता है। यहाँ मेरे दो सेंट हैं।

साथ सबक्वेरी के संबंध

, हाल ही में मैं यह आसान क्या "चरम" इंडेंट और इतने तरह की टिप्पणियां जोड़ने के साथ हो रहा है पालन करने के लिए मिल गया है:

SELECT mt.Col1, mt.Col2, subQ.Dollars 
from MyTable1 mt 
    inner join (-- Get the dollar total for each SubCol 
       select SubCol, sum(Dollars) Dollars 
       from MyTable2 
       group by SubCol) subQ 
    on subQ.SubCol = mt.Col1 
order by mt.Col2 

अन्य प्रतिशत का सवाल है, मैं केवल अपर केस का उपयोग पहले शब्द पर। रन-ऑन प्रश्नों के पृष्ठों के साथ, यह एक नया शुरू होने पर इसे चुनना थोड़ा आसान बनाता है।

आपका माइलेज निश्चित रूप से भिन्न होगा।

9

लड़का यह एक भरा सवाल है। :) इस साइट पर स्मार्ट लोग सही होने के कई तरीके हैं। जैसा कि कहा गया है, तो यहां मैं अपने आप को समझदार रखने के जब जटिल एसक्यूएल बयान के निर्माण है:

select 
    c.customer_id 
    ,c.customer_name 
    ,o.order_id 
    ,o.order_date 
    ,o.amount_taxable 
    ,od.order_detail_id 
    ,p.product_name 
    ,pt.product_type_name 
from 
    customer c 
inner join 
    order o 
    on c.customer_id = o.customer_id 
inner join 
    order_detail od 
    on o.order_id = od.order_id 
inner join 
    product p 
    on od.product_id = p.product_id 
inner join 
    product_type pt 
    on p.product_type_id = pt.product_type_id 
where 
    o.order_date between '1/1/2011' and '1/5/2011' 
and 
    (
     pt.product_type_name = 'toys' 
    or 
     pt.product_type_name like '%kids%' 
    ) 
order by 
    o.order_date 
    ,pt.product_type_name 
    ,p.product_name 

आप रुचि रखते हैं, मैं पोस्ट/आवेषण, अद्यतन के लिए लेआउट भेज सकते हैं और साथ ही साथ सहसंबद्ध सबक्वेरी और जटिल विधेय में शामिल होने के रूप में हटा देता है ।

क्या यह आपके प्रश्न का उत्तर देता है?

+0

लगता है कि ज्यादातर लोग व्हाइटस्पेस से सहमत हैं! – MxyL

+2

मुझे प्रत्येक पंक्ति की परमाणु पर ध्यान केंद्रित करना पसंद है। इस पैटर्न का उपयोग करके, मैं नोड के लिए पदानुक्रम को जल्दी से स्कैन कर सकता हूं जिसे मैं ढूंढ रहा हूं और फिर ड्रिल कर सकता हूं। मेरे अनुभव में, प्राथमिक दोष यह है कि प्रिंटआउट पेपर खाते हैं। सकारात्मक तरफ, वे पेज को शायद ही कभी लपेटते या खून करते हैं। –

+1

मुझे इस लेआउट के बारे में क्या पसंद है, यह पूछने के लिए कि आप अनुमानित परिणामों को वापस क्यों नहीं लौटते हैं, क्वेरी के कुछ हिस्सों पर टिप्पणी करना आसान है। जटिल प्रश्न लिखते समय हमेशा महत्वपूर्ण है। – HLGEM

3

ही सच्चा और सही तरीका एसक्यूएल स्वरूपित करने के लिए है:

SELECT t.mycolumn  AS column1 
     ,t.othercolumn  AS column2 
     ,SUM(t.tweedledum) AS column3 
FROM table1 t 
     ,(SELECT u.anothercol 
       ,u.memaw     /*this is a comment*/ 
     FROM table2  u 
       ,anothertable x 
     WHERE u.bla  = :b1  /*the bla value*/ 
     AND x.uniquecol = :b2  /*the widget id*/ 
     ) v 
WHERE t.tweedledee = v.anothercol 
AND t.hohum  = v.memaw 
GROUP BY t.mycolumn 
     ,t.othercolumn 
HAVING COUNT(*) > 1 
; 

;)

गंभीरता से हालांकि, मैं (पहले से ही सुझाव के रूप में) खंड के साथ उपयोग करने के लिए बहुत जटिल एसक्यूएल प्रश्नों को वश में करना चाहते ।

2

वाह, प्रतिक्रियाओं के बहुत सारे, लेकिन एक चीज़ जो मैंने कई में नहीं देखी है टिप्पणियाँ है! मैं विशेष रूप से बड़े एसक्यूएल स्टेटमेंट के साथ, कई टिप्पणियां जोड़ता हूं। स्वरूपण महत्वपूर्ण है, लेकिन अच्छी तरह से रखा गया और सार्थक टिप्पणियां आपके लिए नहीं बल्कि केवल गरीब आत्मा को कोड बनाए रखने की आवश्यकता है;)