জন্য মাইএসকিউএল 8+: রিকার্সিভ ব্যবহার with
সিনট্যাক্স।
জন্য মাইএসকিউএল 5.x: ব্যবহার ইনলাইন ভেরিয়েবল পথ আইডি, বা নিজের যোগদান করে।
মাইএসকিউএল 8+
with recursive cte (id, name, parent_id) as (
select id,
name,
parent_id
from products
where parent_id = 19
union all
select p.id,
p.name,
p.parent_id
from products p
inner join cte
on p.parent_id = cte.id
)
select * from cte;
সুনির্দিষ্ট মানটি সেই পিতামাতার parent_id = 19
মধ্যে সেট করা উচিত id
যা আপনি সমস্ত বংশধর নির্বাচন করতে চান।
মাইএসকিউএল 5.x
মাইএসকিউএল সংস্করণগুলি যা সাধারণ টেবিল এক্সপ্রেশনগুলি সমর্থন করে না (সংস্করণ 5.7 পর্যন্ত), আপনি নিম্নলিখিত প্রশ্নের সাথে এটি অর্জন করবেন:
select id,
name,
parent_id
from (select * from products
order by parent_id, id) products_sorted,
(select @pv := '19') initialisation
where find_in_set(parent_id, @pv)
and length(@pv := concat(@pv, ',', id))
এখানে একটি ঝাঁকুনি ।
এখানে, নির্দিষ্ট মানটি আপনি যে পিতামাতার সমস্ত বংশধর নির্বাচন করতে চান @pv := '19'
তার id
মধ্যে সেট করা উচিত ।
যদি কোনও পিতামাতার একাধিক সন্তান থাকে তবে এটিও কাজ করবে । যাইহোক, এটি প্রতিটি রেকর্ড শর্তটি পূরণ করা প্রয়োজন parent_id < id
, অন্যথায় ফলাফল সম্পূর্ণ হবে না।
কোনও প্রশ্নের ভিতরে ভেরিয়েবল অ্যাসাইনমেন্ট
এই ক্যোয়ারিতে সুনির্দিষ্ট মাইএসকিউএল সিনট্যাক্স ব্যবহার করা হয়েছে: ভেরিয়েবলগুলি কার্যকর করার সময় নির্ধারিত এবং সংশোধিত হয়। মৃত্যুদন্ড কার্যকর করার আদেশ সম্পর্কে কিছু অনুমান করা হয়:
from
দফা প্রথম মূল্যায়ন করা হয়। সুতরাং যে যেখানে @pv
আরম্ভ হয়।
where
দফা থেকে আহরণ ক্রমানুসারে প্রত্যেকটি রেকর্ডের জন্য মূল্যায়ন করা হয় from
alias লেখা। সুতরাং এই স্থানে কেবলমাত্র এমন শর্তাদি অন্তর্ভুক্ত করা হয় যার জন্য পিতামাতাকে ইতিমধ্যে বংশজাত গাছ হিসাবে উপস্থিত ছিল (প্রাথমিক পিতামাতার সমস্ত বংশধর ক্রমবর্ধমানভাবে যুক্ত হয়েছে @pv
)।
- এই
where
ধারাটির শর্তগুলি যথাযথভাবে মূল্যায়ন করা হয়, এবং মোট ফলাফল নিশ্চিত হওয়ার পরে মূল্যায়ন ব্যাহত হয়। সুতরাং দ্বিতীয় শর্তটি অবশ্যই দ্বিতীয় স্থানে থাকতে হবে, কারণ এটি id
পিতামাতার তালিকায় যুক্ত করে এবং এটি কেবল তখনই ঘটে যখন id
পাসগুলি প্রথম শর্তটি পাস করে। length
ফাংশন শুধুমাত্র করতে বলা হয় নিশ্চিত এই অবস্থা সবসময় সত্য, এমনকি যদি pv
স্ট্রিং কিছু কারণে একটি falsy মান উত্পাদ হবে।
সব মিলিয়ে, কেউ এই অনুমানগুলি নির্ভর করতে খুব ঝুঁকিপূর্ণ খুঁজে পেতে পারে। ডকুমেন্টেশন সাবধান করে:
আপনি প্রত্যাশিত ফলাফল পেতে পারেন, তবে এটির নিশ্চয়তা নেই [...] ব্যবহারকারীর ভেরিয়েবলগুলির সাথে জড়িত এক্সপ্রেশনগুলির জন্য মূল্যায়নের ক্রমটি অপরিবর্তিত।
সুতরাং এটি উপরোক্ত ক্যোয়ারির সাথে ধারাবাহিকভাবে কাজ করলেও, মূল্যায়নের ক্রমটি এখনও পরিবর্তিত হতে পারে, উদাহরণস্বরূপ আপনি যখন শর্ত যুক্ত করেন বা একটি বৃহত্তর ক্যোয়ারিতে ভিউ বা উপ-কোয়েরি হিসাবে এই কোয়েরিটি ব্যবহার করেন। এটি এমন একটি "বৈশিষ্ট্য" যা ভবিষ্যতে মাইএসকিউএল প্রকাশে মুছে ফেলা হবে :
মাইএসকিউএল এর পূর্ববর্তী রিলিজগুলি ছাড়াও বিবৃতিতে কোনও ব্যবহারকারী ভেরিয়েবলের একটি মান নির্ধারণ করা সম্ভব করে SET
। এই কার্যকারিতাটি MySQL 8.0 এ পশ্চাদপটে সামঞ্জস্যের জন্য সমর্থিত তবে মাইএসকিউএল এর ভবিষ্যতে প্রকাশে অপসারণের সাপেক্ষে।
উপরে উল্লিখিত হিসাবে, মাইএসকিউএল 8.0 থেকে আপনার পুনরাবৃত্ত with
সিনট্যাক্স ব্যবহার করা উচিত ।
দক্ষতা
খুব বড় ডেটা সেটগুলির জন্য এই সমাধানটি ধীর হয়ে যেতে পারে, কারণ find_in_set
অপারেশন কোনও তালিকার কোনও নম্বর সন্ধানের সবচেয়ে আদর্শ উপায় নয়, অবশ্যই কোনও তালিকায় নয় যা রেকর্ডের সংখ্যার সাথে একই পরিমাণে আকারে পৌঁছায় records
বিকল্প 1: with recursive
,connect by
আরো অনেক বেশী ডাটাবেস বাস্তবায়ন এসকিউএল: 1999 ISO- র মান WITH [RECURSIVE]
সিনট্যাক্স রিকার্সিভ জিজ্ঞাসার জন্য (যেমন Postgres 8.4+ , এসকিউএল সার্ভার 2005+ , DB2 , ওরাকল 11gR2 + + , SQLite 3.8.4+ , Firebird 2.1 + -এর , ও H2 , HyperSQL 2.1.0+ , Teradata , মারিয়াডিবি 10.2.2+ )। আর যেমন সংস্করণ 8.0, এছাড়াও মাইএসকিউএল এটি সমর্থন । সিনট্যাক্সটি ব্যবহারের জন্য এই উত্তরের শীর্ষটি দেখুন।
কিছু ডাটাবেস যেমন হায়ারারকিকাল বর্ণন আপগুলি জন্য একটি বিকল্প, অ-মানক সিনট্যাক্স আছে CONNECT BY
উপর দফা প্রাপ্তিসাধ্য ওরাকল , DB2 , Informix , CUBRID এবং অন্যান্য ডাটাবেস।
মাইএসকিউএল সংস্করণ 5.7 এ জাতীয় বৈশিষ্ট্য সরবরাহ করে না। যখন আপনার ডাটাবেস ইঞ্জিনটি এই সিনট্যাক্স সরবরাহ করে বা আপনি যে কোনওটিতে স্থানান্তর করতে পারেন, তবে এটি অবশ্যই সবচেয়ে ভাল বিকল্প। যদি তা না হয় তবে নিম্নলিখিত বিকল্পগুলিও বিবেচনা করুন।
বিকল্প 2: পাথ-শৈলীর শনাক্তকারী
বিষয়গুলি অনেক সহজ হয়ে যায় যদি আপনি id
শ্রেণিবদ্ধ তথ্য থাকে এমন একটি মান নির্ধারণ করেন : একটি পথ। উদাহরণস্বরূপ, আপনার ক্ষেত্রে এটি দেখতে এরকম হতে পারে:
ID | NAME
19 | category1
19/1 | category2
19/1/1 | category3
19/1/1/1 | category4
তারপরে আপনার select
চেহারাটি এমন দেখাবে:
select id,
name
from products
where id like '19/%'
বিকল্প 3: পুনরাবৃত্তি স্ব-যোগ দেয়
আপনার শ্রেণিবিন্যাস গাছটি কত গভীর হতে পারে তার যদি আপনি একটি উচ্চতর সীমাটি জানেন তবে আপনি sql
এই জাতীয় মানের কোয়েরি ব্যবহার করতে পারেন :
select p6.parent_id as parent6_id,
p5.parent_id as parent5_id,
p4.parent_id as parent4_id,
p3.parent_id as parent3_id,
p2.parent_id as parent2_id,
p1.parent_id as parent_id,
p1.id as product_id,
p1.name
from products p1
left join products p2 on p2.id = p1.parent_id
left join products p3 on p3.id = p2.parent_id
left join products p4 on p4.id = p3.parent_id
left join products p5 on p5.id = p4.parent_id
left join products p6 on p6.id = p5.parent_id
where 19 in (p1.parent_id,
p2.parent_id,
p3.parent_id,
p4.parent_id,
p5.parent_id,
p6.parent_id)
order by 1, 2, 3, 4, 5, 6, 7;
এই ঝাঁকুনি দেখুন
where
শর্ত নির্দিষ্ট করে যা পিতা বা মাতা আপনি উত্তরপুরুষ উদ্ধার করতে চান। আপনি প্রয়োজন হিসাবে আরও স্তরের সাথে এই কোয়েরি প্রসারিত করতে পারেন।