كيفية حساب وتقييد السجل في استعلام واحد في MYSQL؟

StackOverflow https://stackoverflow.com/questions/802373

  •  03-07-2019
  •  | 
  •  

سؤال

أنا أبحث عن السجلات في الجدول على النحو التالي:

SELECT Id, Name FROM my_table WHERE Name LIKE '%prashant%' LIMIT 0, 10;

الآن، أقوم بإضافة LIMIT للحفاظ على الترحيل الخاص بي.ولكن عندما يبحث المستخدم عن كلمة "prashant"، فإن إجمالي السجلات الموجودة لدي هو 124 كلمة "prashant".ولكن نظرًا لأن الحد المطبق على الاستعلام، فهو يجلب 10 سجلات فقط في برنامج PHP النصي الخاص بي وعندما أقوم بإحصاء متغير mysql في كود PHP فإنه يُرجع إجمالي السجلات التي تم العثور عليها هو 10.

لذلك أريد بشكل أساسي العد والحد باستخدام استعلام واحد، عن طريق إجراء بعض التعديلات في الاستعلام أعلاه، أريد العدد الإجمالي (124) من السجلات.لا أريد تشغيل استعلام عدد (*) منفصل لحساب النتيجة الإجمالية التي عثر عليها الاستعلام فقط.

شكرًا.

هل كانت مفيدة؟

المحلول

SELECT SQL_CALC_FOUND_ROWS
  Id, Name
FROM my_table
WHERE
  Name LIKE '%prashant%'
LIMIT 0, 10;

# Find total rows
SELECT FOUND_ROWS();

مزيد من المعلومات

نصائح أخرى

يدعم MySQL القيام بذلك باستخدام SQL_CALC_FOUND_ROWS كما ذكر ايونوت.ومع ذلك، اتضح ذلك في كثير من الحالات في الواقع، من الأسرع القيام بذلك بالطريقة القديمة باستخدام عبارتين، حيث تكون إحداهما عادية count().ومع ذلك، يتطلب هذا إمكانية إجراء العد باستخدام فحص الفهرس، وهو ما لن يكون هو الحال بالنسبة لهذا الاستعلام بالذات، لكنني أعتقد أنني سأذكر ذلك على أي حال.

هذا للآخرين الذين لديهم نفس الحاجة (مع الأخذ في الاعتبار مرور 3 سنوات على وقت طرح هذا السؤال).

واجهت مشكلة مماثلة ولم أرغب في إنشاء استعلامين.إذن ما فعلته هو إنشاء عمود إضافي للعدد الإجمالي ونقله LIMIT و OFFSET الجمل في النهاية:

SELECT SQL_CALC_FOUND_ROWS * FROM (
    SELECT `id`, `name`
    FROM `my_table`
    WHERE `name` LIKE '%prashant%'
) res,
(SELECT /*CEIL(FOUND_ROWS()/10) AS 'pages',*/ FOUND_ROWS() AS 'total') tot
LIMIT 0, 10

وبالتالي فإن النتيجة هي شيء من هذا القبيل

| id  |      name      | total |
+-----+----------------+-------+
|  1  | Jason Prashant |  124  |
|  2  | Bob Prashant   |  124  |
|  3  | Sam Prashant   |  124  |
|  4  | etc. prashant  |  124  |

وأعتقد أن هذا الحل ليس له أي عيب في التوقيت لأنه يجلب النتيجة مرة واحدة فقط، ثم يستخدم محسوبة بالفعل عدد الصفوف للعمود الإضافي.

في حالة الجداول ضخمة واختيار حقول متعددة (وليس فقط رقم، اسم كما في المثال الخاص بك) وأود أن يوصي لاستخدام 2 استفسار. اختيار عدد (0) أولا مع كل تلك عبارات WHERE وعندها فقط بناء على ترقيم الصفحات، واختيار البيانات الخ وسوف يعمل حقا بشكل أسرع على بعض المواقع التجارة الإلكترونية شعبية، على سبيل المثال.

لا تستخدم SQL_CALC_FOUND_ROWS وFOUND_ROWS()

  1. هناك الأخطاء المبلغ عنها
    هنا: https://bugs.mysql.com/bug.php?id=18454
    و هنا: https://bugs.mysql.com/bug.php?id=19553

  2. بينما يعتمد BENCHMARK في الجداول الصغيرة بشكل أكبر على أشياء أخرى وسيكون الوقت الناتج الذي سيستغرقه SELECT هو نفسه تقريبًا COUNT(0) - لا يزال SQL_CALC_FOUND_ROWS يضع قيودًا على تحسينات قاعدة البيانات LIMIT وORDER BY، لذلك إذا كنت تعتمد عليها لا تستخدم SQL_CALC_FOUND_ROWS

  3. في الجداول الكبيرة، يصبح فرق BENCHMARK كبيرًا حيث قد يستغرق COUNT(0) 0.003 ثانية، وقد يستغرق نفس SQL_CALC_FOUND_ROWS الآن 20 ثانية

بكل المقاييس، يعد COUNT(0) هو الخيار الأفضل

الكونت (0) بناء الجملة:

(SELECT COUNT(0) FROM tableNames WHERE condition) AS alias
// alias is optional but needed if you need to use the result later

لذا فإن إجمالي استعلامك سيبدو هكذا

(SELECT COUNT(0) FROM my_table WHERE name LIKE '%prashant%') AS countResults;

SELECT Id, Name FROM my_table WHERE Name LIKE '%prashant%' LIMIT 0, 10;

وبعد ذلك فقط اتصل بـcountResults أينما كنت في حاجة إليها في مكان آخر...

ميزة أخرى لاستخدام COUNT(0) هي أنه يمكنك استخدامه للبحث في نفس الجدول الموجود هنا أو يمكنك استخدامه للبحث في جدول مختلف...

على سبيل المثال، إذا كان كل شخص تم العثور عليه لديه أيضًا 3، 2، 1، 5 وظائف مختلفة على التوالي...يمكنك فقط إضافة أ

(SELECT COUNT(0) FROM my_jobs_table WHERE name = name_row_in_jobs_table) AS jobs

داخل SELECT الأصلي الخاص بك مثل هذا

SELECT Id, Name (SELECT COUNT(0) FROM my_jobs_table WHERE name = name_row_in_jobs_table) AS jobs FROM my_table WHERE Name LIKE '%prashant%' LIMIT 0, 10;

يعطى لك:

--------------------
| id | Name | jobs |
--------------------
| 1  | Alice| 3    |
--------------------
| 2  | John | 2    |
--------------------
| 3  | Bob  | 1    |
--------------------
| 4  | Jill | 5    |
--------------------

لذلك عند إظهار الاسم[3] (أي.بوب) يمكنك أيضًا إظهار أن بوب لديه وظيفة واحدة عن طريق الاتصال بالوظائف[3]...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top