জেডিটাবেস ব্যবহার করে সাবকিউরি তৈরির পদ্ধতি


31

http://docs.joomla.org/Selecting_data_using_JDatabase , একটি subquery JDatabase ব্যবহার লেখার জন্য নথিভুক্ত পদ্ধতি নয়।

https://gist.github.com/gunjanpatel/8663333 এটি সম্পাদন করার একটি উপায় উদাহরণ দেয় (কয়েকটি বিট বাদ দেওয়া):

$subQuery = $db->getQuery(true);
$query    = $db->getQuery(true);

// Create the base subQuery select statement.
$subQuery->select('*')
    ->from($db->quoteName('#__sub_table'))
    ->where($db->quoteName('subTest') . ' = ' . $db->quote('1'));

// Create the base select statement.
$query->select('*')
    ->from($db->quoteName('#__table'))
    ->where($db->quoteName('state') . ' = ' . $db->quote('1'))
    ->where($db->quoteName('subCheckIn') . ' IN (' . $subQuery->__toString() . ')')
    ->order($db->quoteName('ordering') . ' ASC');

// Set the query and load the result.
$db->setQuery($query);

এটি একটি ভাল, কল্পনাযোগ্য পদ্ধতির মতো বলে মনে হচ্ছে, তবে এর চেয়ে ভাল আর কি আছে?


4
আপনি Qu উপকিউয়েরিতে স্ট্রিং () এ কল করা বাদ দিতে পারেন। জুমলা এটি আপনার জন্য স্বয়ংক্রিয়ভাবে পরিচালনা করবে। এটি বাদ দিয়ে আমি এই একই পদ্ধতিটি ব্যবহার করি এবং এটি আমার পক্ষে ভালভাবে কাজ করছে।
জ্যাচারি ড্রাগার


পছন্দ করুন আপনি কি এর জন্য দায়ী কোডটি প্রদর্শন করতে পারেন?
দিমিত্রি রেকুন

3
@ জাচারিড্রেপার: পিএইচপি (প্রতি সেও জুমলার চেয়ে) আপনার পক্ষে এটি পরিচালনা করে ( __toString()) একটি "যাদু" পদ্ধতি।
মিঃ হোয়েট

হ্যাঁ, আপনাকে ধন্যবাদ W3d।
জ্যাচারি ড্রাগার

উত্তর:


16

হ্যাঁ, আমি যতটা উদ্বিগ্ন, আপনি যেভাবে সাবকোয়ারি তৈরি করেছেন তা হ'ল জুমলার বেশিরভাগ এক্সটেনশান বিকাশকারীরা এটি গ্রহণ করেছেন।

আমি ক্লায়েন্টদের জন্য তৈরি আমার কিছু এক্সটেনশন এবং কাস্টম এক্সটেনশনে একই পদ্ধতিটি ব্যবহার করি।

এটি করার কোনও "অফিসিয়াল" উপায় নেই তবে এটি আপনি যেমনটি দেখিয়েছেন তেমনভাবে আপনাকে কোয়েরি বিল্ডারটি ব্যবহার করতে দেয় এবং এখনও যথেষ্ট পরিমাণে পাঠযোগ্যতা ধরে রাখতে পারে


10

এএফআইএইসি সহজ সাবকিউরিগুলি করার মতো কোনও অন্তর্নির্মিত কাজ নেই, যা সম্ভবত সিস্টেমে একটি ঘাটতি এবং এটি PR এর মাধ্যমে সংশোধন করা উচিত।

তবে, আমি আপনার উদাহরণ সহ কোনও সমস্যা দেখছি না - যথেষ্ট যুক্তিযুক্ত বলে মনে হচ্ছে।

~~~

নীচে @ ডেভিডফ্রিস্টের মন্তব্যের প্রতিক্রিয়া হিসাবে এখানে একটি উদাহরণ দেওয়া আছে। যদিও আমি এটি সম্পর্কে যত বেশি ভাবি ততই আমি ওপিতে প্রদর্শিত আরও সহজ পদ্ধতির পছন্দ করি। কী চলছে তা এটি আরও পরিষ্কার।

$query = $this->db->getQuery(true)
  ->select('a.*')
  ->subQuery()
    ->select('b.*')
    ->from('#__table_b AS b')
    ->as('subQueryResult')
  ->endSubQuery()
  ->from('#__table_a AS a');

1
কীভাবে এটি কাজ করতে পারে তার কোনও ধারণা আছে? আমি যে বিন্যাসটি আপনি এই কাজটি একটি ক্যোয়ারী অবজেক্টে তৈরি করতে ব্যবহার করবেন তা কল্পনা করার চেষ্টা করছি এবং আসলে এই পদ্ধতির চেয়ে সহজ কিছুই মনে হয় না।
ডেভিড ফ্রিশচ

1
এটি এমন একটি subQuerySelectপদ্ধতি তৈরি করা সার্থক হতে পারে যাতে এটি আপনাকে এটি আরও কিছুটা "পরিষ্কারভাবে" করার অনুমতি দেয়। আমি আমার উত্তর সরবরাহ এবং উদাহরণ সম্পাদনা করব।
ডন গিলবার্ট

আমি এটি জুমলা দেখতে পছন্দ করব
2-15 '8:30 এ ফ্রুপেল

3

জুমলা প্ল্যাটফর্ম এপিআই ব্যবহার করে সাব-কোয়েরি রয়েছে এমন ক্যুরিগুলি চালানোর একটি উপায়ও রয়েছে। কিভাবে subqueries ব্যবহার করার জন্য মৌলিক ধারণা উপর ভিত্তি করে তৈরি gunjanpatel

নেস্টেড সেট মডেলগুলিতে ক্যুরিগুলি চালানোর উদাহরণ এখানে :

এসকিউএল কোয়েরি:

-- Find the Immediate Subordinates of a Node
SELECT node.title, (COUNT(parent.id) - (sub_tree.depth + 1)) AS depth
FROM lubd3_usergroups AS node,
        lubd3_usergroups AS parent,
        lubd3_usergroups AS sub_parent,
        (
                SELECT node.id, (COUNT(parent.id) - 1) AS depth
                FROM lubd3_usergroups AS node,
                        lubd3_usergroups AS parent
                WHERE node.lft BETWEEN parent.lft AND parent.rgt
                        AND node.id = 1
                GROUP BY node.id
                ORDER BY node.lft
        )AS sub_tree
WHERE node.lft BETWEEN parent.lft AND parent.rgt
        AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt
        AND sub_parent.id = sub_tree.id
GROUP BY node.id
-- not showing the parent node
HAVING depth = 1
-- showing the parent node
-- HAVING depth <= 1
ORDER BY node.lft;

এবং জুমলা দ্বারা সম্পাদিত রূপান্তরিত ক্যোয়ারী:

// Create the subQuery select statement.
// Nested Set Queries: http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
// CROSS JOIN: http://www.informit.com/articles/article.aspx?p=30875&seqNum=5
$subQuery->select(array('node.id', '(COUNT(parent.id) - 1) AS depth'))
    ->from($db->quoteName('#__usergroups') . 'node')
    ->join('CROSS', $db->quoteName('#__usergroups', 'parent'))
    ->where($db->quoteName('node.lft') . ' BETWEEN  ' . $db->quoteName('parent.lft') . ' AND ' . $db->quoteName('parent.rgt') . ' AND ' . $db->quoteName('node.id') . ' = ' . $db->quote('1'))
    ->group($db->quoteName('node.id'))
    ->order($db->quoteName('node.lft'));

// Create the base select statement.
$query->select(array('node.title', '(COUNT(parent.id) - (sub_tree.depth + 1)) AS depth'))
    ->from($db->quoteName('#__usergroups') . 'node')
    ->join('CROSS', $db->quoteName('#__usergroups', 'parent'))
    ->join('CROSS', $db->quoteName('#__usergroups', 'sub_parent'))
    ->join('CROSS', '(' . $subQuery .') AS sub_tree')
    ->where($db->quoteName('node.lft') . ' BETWEEN  ' . $db->quoteName('parent.lft') . ' AND ' . $db->quoteName('parent.rgt')
    . ' AND ' . $db->quoteName('node.lft') . ' BETWEEN  ' . $db->quoteName('sub_parent.lft') . ' AND ' . $db->quoteName('sub_parent.rgt')
    . ' AND ' . $db->quoteName('sub_parent.id') . ' = ' . $db->quoteName('sub_tree.id'))
    ->group($db->quoteName('node.id'))
    ->having($db->quoteName('depth') . ' = ' . $db->quote('1'))
    ->order($db->quoteName('node.lft'));

// Set the query and load the result.
$db->setQuery($query);
$rowList = $db->loadAssocList();

echo "<pre>";
print_r($rowList);
echo "</pre>";

1
দেখতে দেখতে দেখতে ওপি এর উদাহরণের মতো দেখতে ঠিক একইভাবে: প্রথমে সাবকোয়ারিটি তৈরি করুন এবং তারপরে মূল ক্যোয়ারিতে এটি ব্যবহার করুন। আরও ভাল উপায় আছে কিনা প্রশ্ন ছিল।
ফ্রিপেল

1

আমি স্নিপেটের আমার সংস্করণটি দেব এবং তারপরে আমার ন্যায্যতাটি ব্যাখ্যা করব এবং জুমলা কোডিং স্ট্যান্ডার্ড ম্যানুয়াল থেকে উদ্ধৃতিগুলি অন্তর্ভুক্ত করব (যা উদ্ধৃতি ফর্ম্যাট হবে)।

$subquery = $db->getQuery(true)
    ->select("checkin")
    ->from("#__sub_table")
    ->where("subTest = 1");

$query = $db->getQuery(true)
    ->select("*")
    ->from("#__table")
    ->where([
        "state = 1",
        "subCheckIn IN ({$subQuery})"
    ])
    ->order("ordering");

$db->setQuery($query);

একের পর এক বহু পদ্ধতির সাথে সংযোগ স্থাপনের জন্য কোয়েরি চেইন ব্যবহার করুন, প্রতিটি পদ্ধতির সাথে পরবর্তী পদ্ধতি সমর্থন করতে পারে এমন কোনও বস্তু ফিরিয়ে দেওয়া, এটি পঠনযোগ্যতা উন্নত করে এবং ফলাফলকে সরল করে।

  • আমি প্রথমে অন্তঃস্থ প্রশ্নগুলি লিখি এবং বহিরাগততম কোয়েরিতে অগ্রগতি করি। এটি আমাকে সমস্ত ক্যোয়ারী বিল্ডিং পদ্ধতিগুলিকে সরাসরি পদ্ধতিতে চেইন করতে দেয় getQuery()। কার্যকরভাবে, পৃথক ক্যোয়ারী তৈরি করার সময় ভেরিয়েবলের নামটি একবারে লেখা হয়।
    এখানে কিছু ভারী ক্যোয়ারি নেস্টিংয়ের ভয়ঙ্কর উদাহরণ (যখন আমি ভেবেছিলাম যে শৃঙ্খলিত তীরগুলি লাইন করা খুব সুন্দর)।

  • আমি একই ক্যোয়ারির মধ্যে একাধিক select()এবং / বা where()কল করা এড়ানো চেষ্টা করি কারণ আমি দেখেছি এটি কম অভিজ্ঞ বিকাশকারীদের বিভ্রান্তির দিকে নিয়ে যায় । যেহেতু এই পদ্ধতিগুলি অ্যারে গ্রহণ করে, তাই আমি এগুলিকে নিযুক্ত করতে আরও পাঠযোগ্য এবং আরও ভাল কোডিং অনুশীলন বলে মনে করি।

  • এবং অবশেষে সবচেয়ে বিতর্কিত বিষয় ...

    সারণীর নাম এবং টেবিল কলামের নামগুলি সর্বদা সারণির নাম এবং সারণী কলামগুলি এড়াতে উদ্ধৃতি নাম () পদ্ধতিতে আবদ্ধ থাকা উচিত। কোয়েরিতে যাচাই করা ক্ষেত্রের মানগুলি ডাটাবেসে পাস করার আগে মানটি এড়াতে সর্বদা উদ্ধৃতি () পদ্ধতিতে আবদ্ধ থাকা উচিত। একটি ক্যোয়ারীতে চেক করা পূর্ণসংখ্যার ক্ষেত্রের মানগুলিও (প্রেরণ) টাইপ করা উচিত।

    আমি এই অবস্থান নিয়ে খুব দ্বন্দ্ব বোধ করছি। গত বছর আমি যখন জুমলায় প্রথম এসেছি, আমি ভেবেছিলাম, আমি স্থির মূল্যবোধে অকেজো কল করব না (স্থিতিশীলতা, সুরক্ষা, ক্যোয়ারীর পঠনযোগ্যতার কোনও লাভ নেই)! যাইহোক, আমার নিয়োগকর্তা জুমলা লাইন toeing ধারণা লেগেছে, এবং আমি সত্য বলিয়া স্বীকার করা যে আমি সাধারণত নিয়ম জন্য উচ্চ রসাস্বাদন আছে তাই আমি আমার প্রশ্নের নিচে hosing হয়েছে quote(), (int)এবং quoteName()যা স্ট্রিং সংযুক্তকরণের গাদা অর্থ (সমস্ত যথাযথভাবে ব্যবধানযুক্ত)। আমার কাজের শেষ ফলাফলগুলি ভয়াবহরূপে ফুলে উঠছে ক্যোয়ারী ব্লকগুলি যা এমনকি আমার পক্ষে কঠিন সময় কাটাচ্ছে। সবচেয়ে খারাপ / দীর্ঘতম লাইনগুলি যে উলম্ব স্ট্যাকিংয়ের জন্য নিজেকে ঘৃণা করে না join()সেগুলি হ'ল টেবিলের নাম, উপনামের কারণে কল ON, তারপরে এক বা একাধিক শর্ত যার উদ্ধৃতি প্রয়োজন হতে পারে বা নাও পারে।আমি উপলব্ধি করতে পারি যে এই নীতিটি নবজাতীয় বিকাশকারীদের সুরক্ষার সাথে মাথায় রেখে বাস্তবায়িত করা হয়েছে, তবে আমি নিশ্চিত যে এ নীতিটি যদি কোনওভাবেই সংবেদনশীলতায় মেতে ওঠে যে সমস্ত জুমলা কোডার অজ্ঞ অনুলিপি-অনুলক নয়। মানে, অযথা কল ছাড়াই কোডটি কতটা পরিষ্কার এবং সংক্ষিপ্ত দেখাচ্ছে তা একবার দেখুন।

  • মোপিং আপ হিসাবে:

    • আমি *আমার নির্বাচনী দফায় প্রায় কখনও ব্যবহার করি না
    • আমি কখনও ফোন করি না __toString()
    • আমি পূর্ণসংখ্যার উদ্ধৃতি দিই না, আমি তাদের পূর্ণসংখ্যা হিসাবে ফেলেছি
    • আমি লিখছি না ASCকারণ এটি ডিফল্ট বাছাইয়ের দিক
    • আমি নতুন টেবিলের নাম এবং কলামের নাম তৈরি করার সময় মাইএসকিএল কীওয়ার্ড ব্যবহার না করার সর্বাত্মক চেষ্টা করি
    • ব্যক্তিগত পছন্দের বিষয় হিসাবে আমি আমার পদ্ধতির স্ট্রিং আর্গুমেন্টগুলিতে অভিন্নতা বজায় রাখতে, মাইএসকিএলের একক উদ্ধৃতি থেকে আলাদা করার জন্য ডাবল উদ্ধৃতি ব্যবহার করার প্রবণতা রাখি এবং যাতে আমি পরিবর্তনশীল ইন্টারপোলেশন উপভোগ করতে পারি যা আমি " জটিল সিনট্যাক্স " দিয়ে সাধারণত লিখি ।
    • আমি আমার নেস্টেড ক্যোয়ারীগুলির পাঠযোগ্যতা এবং সাধারণত আমার কোডটিতে সহায়তার জন্য তথ্যমূলক পরিবর্তনশীল নাম এবং মন্তব্য ব্যবহার করি
    • আমি আমার কোডটি আমার হেফাজতে ছাড়ার আগেই এটি পরীক্ষা করি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.