2009-12-01 5 views
2

Я пытаюсь создать оператор MySQL, который будет сортировать по значению, вычисленному в самом выражении. Мои таблицы выглядит следующим образом:MySQL сортировать по вычисленному значению 2 строки

posts 
+----+-----------+--------------+ 
| ID | post_type | post_content | 
+----+-----------+--------------+ 
| 1 |  post |  Hello | 
| 2 |  post |  world | 
+----+-----------+--------------+ 

postmeta 
+---------+----------+------------+ 
| post_id | meta_key | meta_value | 
+---------+----------+------------+ 
|  1 | price |   50 | 
|  1 | retail |  100 | 
|  2 | price |   60 | 
|  2 | retail |   90 | 
+---------+----------+------------+ 

Я пытаюсь вычислить значение называется сбережения (.5 для ID=1, .3 для ID=2), а затем сортировать по ней. Это то, что у меня есть до сих пор, но я не уверен, как выполнить вычисление в двух строках (все, что я нашел, - это вычисление между столбцами).

SELECT wposts.* 
FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta 
WHERE wposts.ID = wpostmeta.post_id 
AND wpostmeta.meta_key = 'Price' 
AND wposts.post_type = 'post' 
ORDER BY wpostmeta.meta_value DESC 

Благодарим за помощь!

+2

Я знаю, что это не полезно, но если вы отвечаете на БД, вы, вероятно, следует реструктурировать его так, что «цена» и «розничной 2 отдельные столбцы ... особенно если те являются всего 2 мета-ключа. Я думаю, что эти вещи типа мета-ключа должны использоваться только для более неясных «настроек» и поэтому вам не нужно будет запускать сложные запросы. – mpen

+0

Ну, это схема Wordpress DB, которая должна быть достаточно общей, чтобы обрабатывать большинство пар ключевых значений для почти любых связанных с сообщением элементов. –

+0

Конечно, он достаточно общий: он перебирает столбцы. Использование реальных столбцов все же было бы лучшим выбором, если это возможно. – 2009-12-01 18:33:54

ответ

2

Это простое соединение, которое рассчитает экономию на сообщение, предполагающее, что meta_value является числовым типом данных.

select posts.id, 
     (retail.meta_value - price.meta_value) * 1.0/retail.meta_value as savings 
    from posts, 
     (select * from postmeta where meta_key = 'price') as price, 
     (select * from postmeta where meta_key = 'retail') as retail 
where posts.id = price.post_id 
    and posts.id = retail.post_id 
    and posts.post_type = 'post' 
order by savings; 


+----+---------+ 
| id | savings | 
+----+---------+ 
| 1 | 0.50000 | 
| 2 | 0.33333 | 
+----+---------+ 
+0

Я показал эту тему сотруднику, который имеет больше опыта SQL, чем я, и он сказал, что ваше решение является лучшим.Я пробовал это, и он работал хорошо, так что спасибо! Я просто изменил «select posts.id» на «select posts. *», Чтобы я мог использовать все остальные данные. Кстати, meta_value не нужно быть числовым, потому что метод вычитания правильно (я думаю) правильно. Еще раз спасибо! –

0

Редактировать: Я неверно истолковал ваш образец вывода .5 как значение 50 центов, а также для .3 = 30 = 90-60 вместо процента, который вы получили от (100 - 50)/100 и (90 - 60)/90. Возможно, вы все равно найдете это полезным, но он не отвечает на заданный вопрос.

SELECT wposts.ID, 
    SUM(wpostmeta.meta_value * (CASE 
    WHEN wpostmeta.meta_key = 'price' THEN -1 
    ELSE 1) 
) AS savings 
FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta 
WHERE wposts.ID = wpostmeta.post_id 
AND wposts.post_type = 'post' 
GROUP BY wposts.ID; 

Ключ суммированием meta_values ​​но листать знак цене, так что вы на самом деле получаете розничную цену минус, сгруппированных по каждому ID, так что совокупная функция SUM касается каждой группы независимо друг от друга. Однако разумно ли это делать всю эту логику, это другой вопрос. :)

(Вы можете настроить этот синтаксис для MySQL.)

2

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

Может быть, вы можете присоединиться к вашей таблицы, а не так что вы получите одну строку:

SELECT wposts.*, pri.meta_value/ret.meta_value 
FROM $wpdb->posts wposts 
INNER JOIN $wpdb->postmeta pri 
     ON pri.post_id = wposts.ID 
     AND pri.meta_key = 'price' 
INNER JOIN $wpdb->postmeta ret 
     ON ret.post_id = wposts.ID 
     AND ret.meta_key = 'retail' 
WHERE wposts.post_type = 'post' 
ORDER BY pri.meta_value/ret.meta_value 

Совет: Никогда не более одной таблицы в предложении FROM.

+0

Хорошо, исправлена ​​опечатка 'pri/ret.ID'' post_id'. +1 –

+2

«Никогда не помещайте в предложение FROM несколько таблиц» - ВОПРОС показывает, что известно как старое соединение ANSI. Синтаксис («,» вместо «INNER JOIN» не является само по себе неправильным, но лучше всего избегать его по причинам, которые хорошо выражены здесь: http://stackoverflow.com/questions/128965/is-there-something-wrong -with-joins-that-dont-use-the-join-keyword-in-sql-or-mys – micahwittman

+0

спасибо за разработку моего совета и исправление моих опечаток :-) – Brimstedt

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