2017-07-06 16 views
7

के साथ SQL से परिणाम प्राप्त करना मैं कुछ (अग्रिम या अधिक जटिल) एसक्यूएल सीखने की कोशिश कर रहा हूं।
मान लें कि मेरे पास हर कार की जानकारी के साथ कारों की एक टेबल है।
फिर मेरे पास कारों के साथ एक और टेबल है, कुछ नए हैं, और कुछ का उपयोग किया जाता है।न्यूनतम, अधिकतम और स्थिति

मैं चाहता हूं कि उपयोगकर्ता एक कार, उदाहरण के लिए होंडा सिविक 2016 देखने में सक्षम हो और कार जानकारी देखें।
लेकिन उपयोगकर्ता को सभी होंडा सिविक 2016 कारों को बेचा जा रहा है, जिसमें उस विशेष वर्ष/मॉडल के लिए उच्चतम और निम्नतम मूल्य शामिल है, जो नए और उपयोग किए जाते हैं।

सभी जानकारी पुनर्प्राप्त करने का सबसे प्रभावी तरीका क्या होगा - कार की जानकारी और किसी पृष्ठ पर प्रदर्शित होने के लिए बेचे जा रहे हैं!

ये मेरी टेबल हैं।

CREATE TABLE Users(
    id BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    name VARCHAR(16) NOT NULL, 
    last VARCHAR(16) NOT NULL, 
    email VARCHAR(128) NOT NULL, 
    phone CHAR(10) NOT NULL, 
    joined DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP 
); 

CREATE TABLE Cars(
    id BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    make VARCHAR(32) NOT NULL, 
    model VARCHAR(32) NOT NULL, 
    year INT(4) NOT NULL, 
    trim VARCHAR(16) NOT NULL 
); 

CREATE TABLE Market(
    id BIGINT(20) NOT NULL AUTO_INCREMENT, 
    user_id BIGINT(20) NOT NULL, 
    car_id BIGINT(20) NOT NULL, 
    condition VARCHAR(5) NOT NULL, 
    notes VARCHAR(1024) NOT NULL, 
    PRIMARY KEY(id), 

    CONSTRAINT cfk FOREIGN KEY (car_id) REFERENCES cars(id) ON DELETE CASCADE ON UPDATE CASCADE, 
    CONSTRAINT ufk FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE 
); 

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

/* Get car information*/ 
SELECT * 
FROM Cars 
WHERE make = 'Honda' 
    AND model = 'Civic' 
    AND year = '2017' 
    AND trim = 'EX'; 

/* I also would like to get the min and max price for this particular car*/ 
/* ?? How ?? */ 

/* Get (new) cars being sold and sellers */ 
SELECT M.*, U.* 
FROM Market M 
INNER JOIN Users ON M.user_id = U.id 
WHERE make = 'Honda' 
    AND model = 'Civic' 
    AND year = '2017' 
    AND color = 'white' 
    AND trim = 'EX' 
    AND condition = 'NEW'; 

/* Get (used) cars being sold and sellers */ 
SELECT M.*, U.* 
FROM Market M 
INNER JOIN Users ON M.user_id = U.id 
WHERE make = 'Honda' 
    AND model = 'Civic' 
    AND year = '2017' 
    AND color = 'white' 
    AND trim = 'EX' 
    AND condition = 'USED'; 

मैं अंत में PHP का उपयोग निम्नलिखित की तरह कुछ प्राप्त करना चाहते हैं:

{ 
    car: { 
     make: "Honda", 
     model: "Civic", 
     year: 2017, 
     trim: "EX" 
    }, 
    market: { 
     new: { 
      min: 'overall min', 
      max: 'overall max', 
      data: [{ 
       seller:{ 
        name: "John", 
        last: "Smith", 
        phone: "xxx-xxx-xxxx", 
        email: "[email protected]", 
       }, 
       car: { 
        price: 15000, 
        color: "white", 
        condition: "used", 
        notes: "Some notes about the car" 
       } 
      }] 
     }, 
     used: { 
      min: 'overall min', 
      max: 'overall max', 
      data: [{ 
       seller:{ 
        name: "John", 
        last: "Smith", 
        phone: "xxx-xxx-xxxx", 
        email: "[email protected]", 
       }, 
       car: { 
        price: 15000, 
        color: "white", 
        condition: "new", 
        notes: "Some notes about the car" 
       } 
      }] 
     } 
    } 
} 

मैं एक बार मैं जानकारी पुनः प्राप्त है कि प्रारूप में डाल करने में सक्षम हूँ। इसके अलावा मुझे डेटाबेस के माध्यम से पेजिंग करना होगा।

मूल रूप से मुझे अमेज़ॅन क्या करने का सबसे अच्छा तरीका जानने पर रूचि है। एक आइटम विभिन्न विक्रेताओं, और विभिन्न कीमतों पर बिक्री के लिए है। अमेज़ॅन बेची जा रही वस्तु के बारे में जानकारी प्रदान करता है; इसकी हालत, मूल्य, विक्रेता इत्यादि। इसके अलावा, अमेज़ॅन आपको सबसे कम, उच्चतम मूल्य और सामान्य रूप से आइटम के बारे में जानकारी देता है। सबसे अच्छा तरीका क्या है?

+1

मुझे लगता है कि आप अपने 'निर्माण तालिका बाजार' में कॉलम 'मूल्य' भूल गए हैं ...', यह पता लगाया कि आपका क्या मतलब है। डेटा प्रकार 'DECIMAL (10,2)' संभवतः 'मूल्य' के लिए है। –

+0

'रंग' भी गायब है .. – SherylHohman

+0

मैं उन टिप्पणियों की सराहना करता हूं, ध्यान देने का ध्यान प्रदर्शन और इसे पूरा करने का सबसे अच्छा तरीका है। मैं बाकी का प्रबंधन करने में सक्षम हूँ! – Gacci

उत्तर

6

चार प्रश्नों ठीक किया जाना चाहिए:

  • एक क्वेरी कार
  • हालत से न्यूनतम/अधिकतम मूल्य प्राप्त करने के लिए एक और क्वेरी
  • फिर प्रत्येक पाने के लिए प्रश्नों के प्रकार के बारे में सामान्य जानकारी प्राप्त करने के लिए नई और प्रयुक्त के लिए उपलब्ध कारों की बाजार सूची। आप इन दो प्रश्नों को आलसी ढंग से कर सकते हैं - सबसे पहले अपने दुकानदारों को मूल कार जानकारी और न्यूनतम/अधिकतम नई/उपयोग की गई कीमतों पर प्रदर्शित करें, और फिर जब आपका दुकानदार उपयोग किए गए नंबर (अमेज़ॅन की तरह) पर क्लिक करता है, तो केवल कारों के लिए मार्केट ऑफ़र लाता है ।

न्यूनतम/अधिकतम बिक्री के लिए, आप एक एकत्रीकरण नहीं करना पड़ता कर रहे हैं ताकि GROUP BY अपने दोस्त है। इसे आज़माएं:

SELECT `condition`, MIN(price) min_price, MAX(price) max_price 
FROM Cars 
JOIN Market ON (Cars.id = Market.car_id) 
WHERE make = 'Honda' 
    AND model = 'Civic' 
    AND year = '2017' 
    AND trim = 'EX' 
GROUP BY `condition`; 

आपकी अन्य प्रश्न अच्छी लगती हैं। जैसे-जैसे टेबल बढ़ते हैं और आप त्वरित प्रश्नों को रखना चाहते हैं, अनुक्रमण मदद करेगा। मूल नियम यह है कि फ़ील्ड जो आपके WHERE भविष्य का हिस्सा हैं, वे अनुक्रमित होने के लिए अच्छे हैं। टेबल के बीच भी JOIN कुंजी आमतौर पर अनुक्रमित होने के लिए अच्छी होती है। Cars(make, model, year, trim) पर एक इंडेक्स आज़माएं।

इसके अलावा, condition MySQL 5.7 में एक आरक्षित शब्द है, यही कारण है कि मैं बैकटिक्स का उपयोग कर बच गया।इसके बजाय cond का उपयोग करने पर विचार करें, और यदि आपके पास केवल कुछ स्थितियां हैं {"नया", "प्रयुक्त"}, ENUM डेटा प्रकार का उपयोग करने पर विचार करें। MIN और MAX से भी सावधान रहें डीबी शब्द आरक्षित हैं।

+0

बस अपनी क्वेरी में एक टाइपो: 'MIN (मूल्य) max_price'' MIN (मूल्य) min_price' होना चाहिए ... –

+0

@EmileEichenberger अच्छी आंख। फिक्स्ड टाइपो। –

+0

धन्यवाद मैं आपकी मदद की सराहना करता हूं! जब टेबल वास्तव में बड़ा हो जाता है तो क्या होगा? क्या मुझे इंडेक्सिंग के बारे में सोचना चाहिए? – Gacci

2

आप दो प्रश्नों के साथ आपको जो जानकारी चाहिए उसे पुनर्प्राप्त कर सकते हैं। उदाहरण के लिए - आप SELECT खंड में सहसंबद्ध सबक्वेरी का उपयोग कर एक क्वेरी में कार की जानकारी के साथ-साथ नए और इस्तेमाल किया कारों के लिए सबसे कम कीमत मिल सकती है:

SELECT c.*, 
    (SELECT MIN(m.price) FROM Market m WHERE m.car_id = c.id and m.condition = 'NEW') as new_min_price, 
    (SELECT MIN(m.price) FROM Market m WHERE m.car_id = c.id and m.condition = 'USED') as used_min_price 
FROM Cars c 
WHERE c.make = 'Honda' 
    AND c.model = 'Civic' 
    AND c.year = '2017' 
    AND c.trim = 'EX' 

सर्वश्रेष्ठ प्रदर्शन के लिए मैं मिश्रित अनुक्रमणिका Cars(make, model, year, trim) और Market(car_id, condition, price) पैदा करेगा। पहली अनुक्रमणिका में कॉलम का क्रम महत्वपूर्ण नहीं है और आप इसे बदल सकते हैं। ऑप्टिमाइज़र आपके द्वारा परिभाषित आदेश के लिए निष्पादन योजना को समायोजित कर सकता है। हालांकि दूसरी सूचकांक के लिए आदेश सबसे कम कीमत सबसे प्रभावी रूप से प्राप्त करने के लिए इस तरह से होना चाहिए। यदि आपके पास Market(car_id) पर एक अनुक्रमणिका है (जो शायद फ़ॉरेनी कुंजी परिभाषा द्वारा बनाई गई है), तो आप इसे छोड़ सकते हैं। इसके बजाय नई समग्र अनुक्रमणिका का उपयोग किया जा सकता है।

ध्यान दें कि मैंने उच्चतम मूल्य शामिल नहीं किया है, क्योंकि मुझे नहीं लगता कि कोई भी परवाह करता है। लेकिन आप इसे उसी तरह प्राप्त कर सकते हैं जैसे MIN() के बजाय MAX() का उपयोग करके आप सबसे कम कीमत प्राप्त कर सकते हैं।

वहाँ एक और तरीका है एक ही डेटा प्राप्त करने के लिए "सशर्त एकत्रीकरण" का उपयोग कर रहा है:

SELECT c.*, 
    MIN(CASE m.condition = 'NEW' THEN m.price END) as new_min_price, 
    MIN(CASE m.condition = 'USED' THEN m.price END) as used_min_price 
FROM Cars c 
JOIN Market m ON m.car_id = c.id 
WHERE c.make = 'Honda' 
    AND c.model = 'Civic' 
    AND c.year = '2017' 
    AND c.trim = 'EX' 
GROUP BY c.id 

लेकिन इस क्वेरी के बाद से इंजन सभी प्रस्तावों के माध्यम से लूप करने की आवश्यकता होगी, सबसे अच्छा तरीका में अनुक्रमित उपयोग नहीं कर सकते सबसे कम कीमत खोजने के लिए।

अब Market तालिका से सभी ऑफ़र प्राप्त करने के लिए, आपको दो प्रश्नों (प्रत्येक शर्त के लिए एक) निष्पादित करने की आवश्यकता नहीं है। आप उन्हें एक प्रश्न के साथ ला सकते हैं और परिणाम को अपनी आवेदन भाषा में condition फ़ील्ड द्वारा परिणाम दे सकते हैं। चूंकि आप पहले से ही car_id पहली क्वेरी से जानते हैं, तो आप इसे खोज मानदंड के रूप में उपयोग कर सकते हैं, इसलिए आपको cars तालिका को फिर से स्पर्श करने की आवश्यकता नहीं है। (ध्यान दें कि अपने पिछले दो प्रश्नों cars मेज के साथ एक में शामिल हों के बिना काम नहीं होता है, के बाद से बाजार तालिका स्तंभ make, model, year और trim जरूरत नहीं है।)

SELECT 
    m.condition 
    m.id as market_id, 
    m.user_id, 
    u.name, 
    u.last 
FROM Market m 
INNER JOIN Users u ON m.user_id = u.id 
WHERE m.car_id = ? 
ORDER BY price 

ध्यान दें कि अगर आप SELECT m*, u* का उपयोग करें, id फ़ील्ड संदिग्ध होगा क्योंकि यह दोनों तालिकाओं में परिभाषित है। तो आपको उन सभी फ़ील्ड को सूचीबद्ध करना चाहिए जिन्हें आप लाने के लिए चाहते हैं और m.id as market_id जैसे अस्पष्ट कॉलम के लिए उपनाम का उपयोग करना चाहिए।

आपने जिस भाषा का उपयोग किया है उसका उल्लेख नहीं किया है - इसलिए मैं आपको condition फ़ील्ड द्वारा परिणाम को समूहबद्ध करने का बिल्कुल सही नहीं बता सकता। उदाहरण के लिए PHP पीडीओ के साथ आप PDO::FETCH_GROUP मोड का उपयोग कर सकते हैं। हालांकि यदि आपकी भाषा ऐसी कार्यक्षमता का समर्थन नहीं करती है तो आप परिणाम को एक साधारण लूप में समूह/विभाजित कर सकते हैं।

0

बहुत से लोग इसे पसंद नहीं कर सकते हैं लेकिन मैंने एमएस एक्सेस का उपयोग कर कुछ जटिल SQL कथन हल किए हैं। सबसे पहले डिजाइन टेबल और रिश्तों के लिए एमएस एक्सेस का उपयोग करें। फिर प्रश्न बनाने के लिए क्वेरी बिल्डर का उपयोग करें। फिर SQL स्टेटमेंट देखने के लिए क्वेरी बिल्डर को SQL व्यू में बदलें। अन्य डीबी इंजनों पर इस एसक्यूएल कोड का उपयोग करने के लिए मामूली परिवर्तन की आवश्यकता है।

एसक्यूएल कोडिंग किंग्स एमएस एक्सेस से नफरत करते हैं लेकिन हकीकत में, यह किसी भी डेटाबेस को बनाने के लिए शुरू करने का सबसे अच्छा विकास उपकरण है। यह आसान और तेज परिवर्तन की अनुमति देता है, और एकल उपयोगकर्ता मोड में सबसे तेज़ डीबी है।

यदि आप बहुत सारे डेटाबेस बनाने की योजना बना रहे हैं और एसक्यूएल कोडिंग राजा बनकर समय बचाने के लिए चाहते हैं तो हमें विकास उपकरण के रूप में एमएस एक्सेस!

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