2012-03-25 3 views
1

У меня есть две таблицы ... первый - это список страниц с (page_id, page_title) строками. Второй - список элементов на тех страницах, каждый из которых имеет цену (item_id, page_id, item_title, item_price).MYSQL выбрать 3 результата каждого «id страницы»

Я хотел бы захватить верхние три пункта с каждой страницы (сначала по заказу самой высокой item_price) со страницей, имеющей кумулятивно самую высокую цену, заказанную в первую очередь. Это намного превосходит мои возможности MYSQL, и я ищу советы о том, как сделать это наиболее эффективным! :) Благодаря!

+0

Вы хотите получить 3 верхних позиций для всех страниц одновременно или по одной странице за раз? –

+0

Я хочу вывести список всех страниц, отображающих три верхние позиции каждой страницы (верхняя - самая высокая цена, а страницы упорядочены по кумулятивной максимальной цене). Благодаря! – PotatoFro

+0

Заданный вопрос, откуда вы узнали, на какую страницу он принадлежит? –

ответ

0

Вы можете сделать это несколькими различными способами. То, что я сделал бы, это запустить один запрос, который говорит: «Получите все страницы, упорядоченные по сумме их элементов», а затем пропустите их через php, и для каждого из них сделайте «получить мне верхние 3 элемента для текущей страницы», ,

Имеют смысл?

Query один (непроверенный, написанный на моем телефоне):

SELECT p.page_name, (SELECT SUM(item_price) FROM items WHERE page_id = p.page_id) AS cumulative_price FROM pages p ORDER BY cumulative_price DESC; 

Запрос два (также непроверенный) пробегает по результатам запроса одного:

SELECT * FROM items WHERE page_id = '$currentPageId' ORDER BY item_price DESC LIMIT 3; 
+0

Очевидно, вы включили бы идентификатор страницы в первый запрос для использования во втором. –

0
  • Я предполагаю, что каждый PAGE_ID равен item_id, и вот как они связаны друг с другом. (Если нет, пожалуйста, поправьте меня.)
  • Я просто буду называть второй стол «таблица2» и ITEM_ID Я смотрю вверх «SOME_ITEM_ID»

    SELECT * FROM `table2` WHERE `item_id` = 'SOME_ITEM_ID' ORDER BY `item_price` DESC; 
    

В английском языке, что это высказывание:

Выбрать все от table2 где item_id является это и упорядочить список по ITEM_PRICE в порядке убывания

Эта инструкция SQL вернет каждый удар, но вы просто выведете первые три кода.

+0

Мой плохой здесь - я редактировал оригинальное сообщение. Таблица элементов привязывается к таблице страниц через «page_id». Элементы имеют как «item_id», так и «page_id». – PotatoFro

0

Моя кишка говорит мне, что, вероятно, не быстрее способ сделать это, чем сделать для цикла в приложении через все страницы, делая немного select item_price from item where page_id = ? order by item_price desc limit 3 для каждого paqe, и, возможно, торчащие результаты в что-то вроде memcached, поэтому вы не слишком сильно обходите свою базу данных.

Но мне нравится вызов, поэтому я все равно попытаюсь.

SELECT p1.*, i1.*, 
 (SELECT count(*) 
    FROM items i2 
    WHERE i1.item_price < i2.item_price 
    AND p1.page_id = i2.page_id) price_rank, 
FROM pages p1 
LEFT OUTER JOIN items i1 
ON p1.page_id = i1.page_id 
WHERE price_rank < 3; 

Этот странный суб-выбор будет, вероятно, сделать очень много работы для каждой строки в items. многие другие функции RDBMses имеют функцию, называемую оконными функциями, которые могут сделать это намного элегантнее. Например, если вы используете PostgreSQL, вы могли бы написать:

SELECT p1.*, i1.*, 
    RANK(i1.item_price) 
    OVER (PARTITION BY p1.page_id 
      ORDER BY i1.item_price DESC) price_rank 
FROM pages p1 
LEFT OUTER JOIN items i1 
ON p1.page_id = i1.page_id 
WHERE price_rank <= 3; 

И планировщик устроил бы посетить строки в порядке, что приводит к рангу происходящим правильно.

Смежные вопросы