webForumDet fria alternativet

Pageningproblem

Databaser & SQLur Databashanterare & SQL

2 svar · 337 visningar · startad av Ramzeus

Medlem sedan mars 200642 inlägg
Frågan#1

Jag håller på med en lite mer avancerad sökfunktion.

Jag har fått till en SQL-fråga som fungerar, men den är ganska så stor och komplicerad för att klara av att hitta allt jag vill hitta.
Den går relativt snabbt just nu, men jag misstänker att den kan komma att gå segt när databasen börjar fyllas upp lite.

För att hantera många sökträffar så använder jag mig av pagening på detta viset:
<< föregående, 1, 2, 3, 4, 5, nästa >>
För att kunna generera listan med de olika sidnummren så behöver jag ta fram hur många totala träffar jag har i databasen. Jag har gjort detta genom att köra min SQL-fråga två gånger i databasen. Ena gången med COUNT(*) och utan LIMIT och sedan en gång till med LIMIT.

Min fråga är: Finns det något sätt att förbättra detta, dvs att få ut totala antalet träffar utan att köra frågan två gånger?

EDIT: Jag kör MySQL 5

Så här kan t.ex en fråga se ut:

SELECT 
	COALESCE(m.reg_nr, m.chassis_nr, m.serial_code) AS machine, 
	wo.short_description,
	wo.id, 
	wo.dt_created, 
	wo.dt_deadline, 
	wo.status, 
	IF(wo.calendar_id IS NULL OR wo.calendar_id=0, IF(wo.queue_id IS NULL OR wo.queue_id=0, 'none', 'queue'), 'calendar') AS schedule,
	c.name AS customer,
	u.username AS user,
	c.id AS customer_id,
	m.id AS machine_id,
	u.id AS user_id
FROM mfab_work_order wo
LEFT JOIN mfab_customers c ON c.id=wo.customer_id
LEFT JOIN mfab_machines m ON m.id=wo.machine_id
LEFT JOIN mfab_users u ON u.id=wo.user_id
WHERE 
(
	wo.id LIKE '%Patrik%'
	OR wo.status LIKE '%Patrik%'
	OR wo.short_description LIKE '%Patrik%'
	OR wo.long_description LIKE '%Patrik%'
	OR wo.customer_id IN
	(
		SELECT _c.id FROM mfab_customers _c
		WHERE
		(
			_c.id LIKE '%Patrik%'
			OR _c.number LIKE '%Patrik%'
			OR _c.name LIKE '%Patrik%'
			OR _c.short_name LIKE '%Patrik%'
			OR _c.mailing_address LIKE '%Patrik%'
			OR _c.mailing_address2 LIKE '%Patrik%'
			OR _c.visiting_address LIKE '%Patrik%'
			OR _c.zipcode LIKE '%Patrik%'
			OR _c.city LIKE '%Patrik%'
			OR _c.telephone LIKE '%Patrik%'
			OR _c.telephone2 LIKE '%Patrik%'
			OR _c.delivery_name LIKE '%Patrik%'
			OR _c.delivery_address LIKE '%Patrik%'
			OR _c.delivery_address2 LIKE '%Patrik%'
			OR _c.delivery_visiting_address LIKE '%Patrik%'
			OR _c.delivery_zipcode LIKE '%Patrik%'
			OR _c.delivery_city LIKE '%Patrik%'
			OR _c.delivery_telephone LIKE '%Patrik%'
			OR _c.delivery_telephone2 LIKE '%Patrik%'
			OR _c.reference LIKE '%Patrik%'
			OR _c.organisation_number LIKE '%Patrik%'
			OR _c.bgiro LIKE '%Patrik%'
			OR _c.pgiro LIKE '%Patrik%'
			OR _c.remark1 LIKE '%Patrik%'
			OR _c.remark2 LIKE '%Patrik%'
		)
	)
	OR wo.machine_id IN
	(
		SELECT 
			_m.id
		FROM mfab_machines _m
		LEFT JOIN mfab_machine_owners _mo ON _mo.machine_id=_m.id
		LEFT JOIN mfab_customers __c ON __c.id=_mo.customer_id
		WHERE 
		(
			(
				_mo.dt_start IN
				(
					SELECT DISTINCT MAX(dt_start) FROM mfab_machine_owners __mo
					WHERE __mo.machine_id=_m.id
				)
				AND _mo.dt_end IS NULL
			) 
			OR _mo.dt_start IS NULL
		)
		AND 
		(
			_m.id LIKE '%Patrik%'
			OR _m.reg_nr LIKE '%Patrik%'
			OR _m.chassis_nr LIKE '%Patrik%'
			OR _m.serial_code LIKE '%Patrik%'
			OR _m.object_type LIKE '%Patrik%'
			OR _m.model LIKE '%Patrik%'
			OR _m.manufacturer LIKE '%Patrik%'
			OR _m.description LIKE '%Patrik%'
			OR 
			(
				SELECT customer_id FROM mfab_machine_owners ___mo
				WHERE machine_id=_m.id IN 
				(
					(
						___mo.customer_id IN 
						(
							SELECT ___c.id FROM mfab_customers ___c
							WHERE
							(
								___c.id LIKE '%Patrik%'
								OR ___c.number LIKE '%Patrik%'
								OR ___c.name LIKE '%Patrik%'
								OR ___c.short_name LIKE '%Patrik%'
								OR ___c.mailing_address LIKE '%Patrik%'
								OR ___c.mailing_address2 LIKE '%Patrik%'
								OR ___c.visiting_address LIKE '%Patrik%'
								OR ___c.zipcode LIKE '%Patrik%'
								OR ___c.city LIKE '%Patrik%'
								OR ___c.telephone LIKE '%Patrik%'
								OR ___c.telephone2 LIKE '%Patrik%'
								OR ___c.delivery_name LIKE '%Patrik%'
								OR ___c.delivery_address LIKE '%Patrik%'
								OR ___c.delivery_address2 LIKE '%Patrik%'
								OR ___c.delivery_visiting_address LIKE '%Patrik%'
								OR ___c.delivery_zipcode LIKE '%Patrik%'
								OR ___c.delivery_city LIKE '%Patrik%'
								OR ___c.delivery_telephone LIKE '%Patrik%'
								OR ___c.delivery_telephone2 LIKE '%Patrik%'
								OR ___c.reference LIKE '%Patrik%'
								OR ___c.organisation_number LIKE '%Patrik%'
								OR ___c.bgiro LIKE '%Patrik%'
								OR ___c.pgiro LIKE '%Patrik%'
								OR ___c.remark1 LIKE '%Patrik%'
								OR ___c.remark2 LIKE '%Patrik%'
							)
						)
					)
				)
			)
		)
		GROUP BY _m.id
	)
)
 ORDER BY name  ASC  LIMIT 50
Medlem sedan dec. 200012 464 inlägg
#2

Från manualen

FOUND_ROWS()

A SELECT statement may include a LIMIT clause to restrict the number of rows the server returns to the client. In some cases, it is desirable to know how many rows the statement would have returned without the LIMIT, but without running the statement again. To obtain this row count, include a SQL_CALC_FOUND_ROWS option in the SELECT statement, and then invoke FOUND_ROWS() afterward:

mysql> SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
-> WHERE id > 100 LIMIT 10;
mysql> SELECT FOUND_ROWS();

Medlem sedan mars 200642 inlägg
#3

Du är så jävla bäst! Tack!
Jag är sämst på att kolla manualen :)

134 ms totalt · 3 externa anrop · v20260731065814-full.4bcf49fe
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
131 ms — hämta tråd, inlägg och bilagor (db)