Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

MySQL:एक स्टेटमेंट पर कई टेबल्स में शामिल हों

MySQL में पुनरावर्ती क्वेरी के साथ ट्री नोड से सभी वंशज कैसे प्राप्त करें?

यह वास्तव में MySql के लिए एक समस्या है, और यह इस प्रश्न का एक महत्वपूर्ण बिंदु है, लेकिन आपके पास अभी भी कुछ विकल्प हैं।

मान लें कि आपके पास ऐसा नमूना डेटा है, जितना आपके नमूने के रूप में नहीं बल्कि प्रदर्शित करने के लिए पर्याप्त है:

create table treeNode(
id int, parent_id  int,  name varchar(10), type varchar(10),level int);
insert into treeNode 
(id, parent_id, name, type, level) values 
( 1,  0,  'C1    ', 'CATEGORY', 1),
( 2,  1,  'C1.1  ', 'CATEGORY', 2),
( 3,  2,  'C1.1.1', 'CATEGORY', 3),
( 4,  1,  'C1.2  ', 'CATEGORY', 2),
( 5,  4,  'C1.2.1', 'CATEGORY', 3),
( 3,  8,  'G1.1.1',    'GROUP', 3),
( 4,  9,  'G1.2  ',    'GROUP', 2),
( 5,  4,  'G1.2.1',    'GROUP', 3),
( 8,  9,  'G1.1  ',    'GROUP', 2),
( 9,  0,  'G1    ',    'GROUP', 1);

पहली पसंद:लेवल कोड

ट्रीनोड तालिका में नाम कॉलम के नमूना डेटा की तरह। (मुझे नहीं पता कि इसे अंग्रेजी में कैसे कहें, level code के सही एक्सप्रेशन के बारे में मुझे कमेंट करें ।)

C1 . के सभी वंशज प्राप्त करने के लिए या G1 इस तरह सरल हो सकता है:

select * from treeNode where type = 'CATEGORY' and name like 'C1%' ;
select * from treeNode where type = 'GROUP' and name like 'G1%' ;

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

इस दृष्टिकोण के साथ, कथन आप शामिल होने के साथ want चाहते हैं हो सकता है:

SELECT distinct p.* --if there is only one tree node for a product, distinct is not needed
FROM product p
JOIN product_type pt
     ON pt.id= p.parent_id -- to get product type of a product
JOIN linked_TreeNode LC
     ON LC.product_id= p.id -- to get tree_nodes related to a product
JOIN (select * from treeNode where type = 'CATEGORY' and name like 'C1%' ) C --may replace C1% to concat('$selected_cat_name','%')
     ON LC.treeNode_id = C.id
JOIN (select * from treeNode where type = 'GROUP' and name like 'G1%' ) G --may replace G1% to concat('$selected_group_name','%')
     ON LC.treeNode_id = G.id
WHERE pt.name = '$selected_type'  -- filter selected product type, assuming using product.name, if using product.parent_id, can save one join by pt like your original sql

मीठा, है ना?

दूसरा विकल्प:लेवल नंबर

डीडीएल में दिखाए गए अनुसार ट्रीनोड टेबल में एक लेवल कॉलम जोड़ें।

लेवल नंबर लेवल कोड . की तुलना में बनाए रखना बहुत आसान है आवेदन में।

C1 . के सभी वंशज प्राप्त करने के लिए स्तर संख्या के साथ या G1 इस तरह की एक छोटी सी तरकीब चाहिए:

SELECT id, parent_id, name, type, @pv:=concat(@pv,',',id) as link_ids 
  FROM (select * from treeNode where type = 'CATEGORY' order by level) as t
  JOIN (select @pv:='1')tmp
 WHERE find_in_set(parent_id,@pv)
    OR find_in_set(id,@pv);
 -- get all descendants of `C1`

SELECT id, parent_id, name, type, @pv:=concat(@pv,',',id) as link_ids 
  FROM (select * from treeNode where type = 'GROUP' order by level) as t
  JOIN (select @pv:=',9,')tmp
 WHERE find_in_set(parent_id,@pv)
    OR find_in_set(id,@pv) ;

यह दृष्टिकोण पहले की तुलना में धीमा है, लेकिन फिर भी पुनरावर्ती क्वेरी की तुलना में तेज़ है।

प्रश्न के लिए पूर्ण sql छोड़े गए। केवल उपरोक्त दो प्रश्नों के साथ C और G की उन दो उपश्रेणियों को बदलने की आवश्यकता है।

नोट:

कई समान दृष्टिकोण हैं जैसे यहां , यहां , या यहां तक ​​कि यहां . स्तर संख्या या स्तर कोड द्वारा आदेश दिए जाने तक वे काम नहीं करेंगे। आप इस SqlFiddle में अंतिम क्वेरी का परीक्षण कर सकते हैं order by level changing बदलकर करने के लिए order by id अंतर देखने के लिए।

दूसरा विकल्प:नेस्टेड सेट मॉडल

कृपया इस ब्लॉग का संदर्भ लें , मैंने अभी तक परीक्षण नहीं किया है। लेकिन मुझे लगता है कि यह पिछली दो पसंद के समान है।

सभी वंशजों की आईडी को उनके बीच संलग्न करने के लिए आपको ट्रीनोड तालिका में एक बाएं नंबर और एक सही संख्या जोड़ने की आवश्यकता है।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL वर्कबेंच द्वारा निर्यात की गई CREATE स्क्रिप्ट में दूसरे कंप्यूटर पर सिंटैक्स त्रुटि है

  2. एक ही क्वेरी में अलग-अलग मानों के साथ कई पंक्तियों को अपडेट करें - MySQL

  3. SQL:प्रत्येक व्यक्ति के लिए सबसे सामान्य मान लौटाना

  4. किसी पोस्ट को कितनी बार पढ़ा गया, यह जांचने के लिए अलग-अलग गिनती के साथ गिनती करना

  5. पैरेंट आईडी के क्रम में रिकॉर्ड का चयन