MySQL में किसी कॉलम का मान विशिष्ट मान (जैसे isMarried = 0) होने वाली पंक्तियों को चुनकर, दूसरे कॉलम (ClientId) द्वारा समूहित करने के लिए GROUP BY के साथ HAVING का उपयोग करें। ध्यान दें: यह पैटर्न MySQL के ONLY_FULL_GROUP_BY मोड पर निर्भर करता है।
सिंटैक्स
SELECT column1, column2, filter_column FROM table_name GROUP BY group_column HAVING filter_column = value;
व्यावहारिक उदाहरण
टेबल बनाएं:
mysql> CREATE TABLE DemoTable1344 (
SequenceId INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
ClientId INT,
isMarried TINYINT(1)
);
डेटा डालें:
mysql> INSERT INTO DemoTable1344(ClientId, isMarried) VALUES(4567, 0); mysql> INSERT INTO DemoTable1344(ClientId, isMarried) VALUES(9876, 0); mysql> INSERT INTO DemoTable1344(ClientId, isMarried) VALUES(5432, 1); mysql> INSERT INTO DemoTable1344(ClientId, isMarried) VALUES(4567, 1); mysql> INSERT INTO DemoTable1344(ClientId, isMarried) VALUES(9873, 0);
डेटा देखें:
mysql> SELECT * FROM DemoTable1344;
+------------+----------+-----------+ | SequenceId | ClientId | isMarried | +------------+----------+-----------+ | 1 | 4567 | 0 | | 2 | 9876 | 0 | | 3 | 5432 | 1 | | 4 | 4567 | 1 | | 5 | 9873 | 0 | +------------+----------+-----------+
ClientId द्वारा समूहित, केवल isMarried=0 वाले समूह
mysql> SELECT SequenceId, ClientId, isMarried
-> FROM DemoTable1344
-> GROUP BY ClientId
-> HAVING isMarried = 0;
परिणाम
+------------+----------+-----------+ | SequenceId | ClientId | isMarried | +------------+----------+-----------+ | 1 | 4567 | 0 | | 2 | 9876 | 0 | | 5 | 9873 | 0 | +------------+----------+-----------+
व्याख्या और चेतावनी
क्या होता है
GROUP BY ClientId- ClientId के अनुसार समूह: 4567 (2 पंक्तियां), 9876 (1), 5432 (1), 9873 (1)HAVING isMarried = 0- प्रत्येक समूह के लिए, MySQL **मनमाने ढंग से** एक पंक्ति काisMarriedमान चुनता है- यदि चुनी गई पंक्ति का
isMarried = 0है, तो समूह शामिल होता है
⚠️ समस्या: अनिश्चित व्यवहार
ClientId 4567 की दो पंक्तियां हैं: isMarried = 0 (SequenceId 1) और isMarried = 1 (SequenceId 4)।
- MySQL
ONLY_FULL_GROUP_BY**अक्षम** होने पर: मनमानी पंक्ति चुनता है (आमतौर पर पहली) - MySQL
ONLY_FULL_GROUP_BY**सक्षम** होने पर (डिफ़ॉल्ट 5.7+): **त्रुटि** -SequenceIdऔरisMarriedन तो GROUP BY में हैं न एग्रीगेट में
सही दृष्टिकोण: स्पष्ट एग्रीगेशन
विकल्प 1: WHERE से पहले फ़िल्टर करें (अनुशंसित)
SELECT SequenceId, ClientId, isMarried FROM DemoTable1344 WHERE isMarried = 0;
+------------+----------+-----------+ | SequenceId | ClientId | isMarried | +------------+----------+-----------+ | 1 | 4567 | 0 | | 2 | 9876 | 0 | | 5 | 9873 | 0 | +------------+----------+-----------+
विकल्प 2: ClientId प्रति कोई भी isMarried=0 हो (EXISTS तर्क)
SELECT DISTINCT ClientId FROM DemoTable1344 WHERE isMarried = 0;
विकल्प 3: एग्रीगेट फ़ंक्शन के साथ (मानक SQL)
SELECT ClientId, MIN(isMarried) AS MinMarried, MAX(isMarried) AS MaxMarried FROM DemoTable1344 GROUP BY ClientId HAVING MIN(isMarried) = 0; -- कम से कम एक 0 हो
विकल्प 4: पहली पंक्ति चुनें (MySQL 8.0+ ROW_NUMBER)
WITH ranked AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY ClientId ORDER BY SequenceId) AS rn
FROM DemoTable1344
)
SELECT SequenceId, ClientId, isMarried
FROM ranked
WHERE rn = 1 AND isMarried = 0;
सारांश
| इरादा | सही क्वेरी |
|---|---|
| सभी isMarried=0 पंक्तियां | WHERE isMarried = 0 |
| कम से कम एक isMarried=0 वाले ClientId | GROUP BY ClientId HAVING MIN(isMarried) = 0 |
| सभी isMarried=0 वाले ClientId | GROUP BY ClientId HAVING MAX(isMarried) = 0 |
| प्रति ClientId पहली isMarried=0 पंक्ति | ROW_NUMBER() या सबक्वेरी |
मूल क्वेरी ONLY_FULL_GROUP_BY बंद होने पर ही काम करती है और **अविश्वसनीय** है। उत्पादन कोड में स्पष्ट एग्रीगेशन या WHERE फ़िल्टर उपयोग करें।