0

i'm pulling my hair out here:

I have a sql statement that is part of an ajax call:

SELECT $wpdb->commentmeta.meta_value, $wpdb->comments.comment_ID, $wpdb->comments.comment_date, $wpdb->comments.user_id, $wpdb->comments.comment_content, $wpdb->comments.comment_author 
FROM $wpdb->commentmeta 
JOIN $wpdb->comments ON $wpdb->comments.comment_ID = $wpdb->commentmeta.comment_id 
WHERE $wpdb->commentmeta.meta_key = '_commentsvote' 
AND $wpdb->comments.comment_date >='" . $current_year . "-" . $current_month . "-01' 
AND $wpdb->comments.comment_date <='" . $current_year . "-" . $current_month . "-31' 
ORDER BY $wpdb->commentmeta.meta_value DESC

the statement works great, and returns results, however, the order is off. now, i know this is because the meta_value is actually a varchar, and not an int. so, the internets told me to do either a convert or cast:

Convert: 
SELECT $wpdb->commentmeta.meta_value, $wpdb->comments.comment_ID, $wpdb->comments.comment_date, $wpdb->comments.user_id, $wpdb->comments.comment_content, $wpdb->comments.comment_author 
FROM $wpdb->commentmeta 
JOIN $wpdb->comments ON $wpdb->comments.comment_ID = $wpdb->commentmeta.comment_id 
WHERE $wpdb->commentmeta.meta_key = '_commentsvote' 
AND $wpdb->comments.comment_date >='" . $current_year . "-" . $current_month . "-01' 
AND $wpdb->comments.comment_date <='" . $current_year . "-" . $current_month . "-31' 
ORDER BY CONVERT(INT, $wpdb->commentmeta.meta_value) DESC

CAST
SELECT $wpdb->commentmeta.meta_value, $wpdb->comments.comment_ID, $wpdb->comments.comment_date, $wpdb->comments.user_id, $wpdb->comments.comment_content, $wpdb->comments.comment_author 
FROM $wpdb->commentmeta 
JOIN $wpdb->comments ON $wpdb->comments.comment_ID = $wpdb->commentmeta.comment_id 
WHERE $wpdb->commentmeta.meta_key = '_commentsvote' 
AND $wpdb->comments.comment_date >='" . $current_year . "-" . $current_month . "-01' 
AND $wpdb->comments.comment_date <='" . $current_year . "-" . $current_month . "-31' 
ORDER BY CAST($wpdb->commentmeta.meta_value AS INT) DESC

I keep getting sql errors on both of these when i run it as a sql statement (obviously, i convert the $wpdp to just say wp_) out of wordpress. the error is non specific - i.e. "you have an error near as int" for example.

so, two questions, first one is wp specific, and the second is a sql:

  1. i'm pretty sure there's a way to write all this as an arg array i can pass into wp_query, but i'm unsure of how to do a join. code examples here would be super helpful.
  2. why why WHY is this sql statement unwilling to convert that last colomn to an int?

Thanks Wp and SQL geniuses for reading!

4

1 回答 1

0

简短的版本是你不能CONVERT-INT正确的类型是SIGNED. 阅读更多关于CASTCONVERT。也就是说,您应该进行一些其他更改以使代码更具可读性和安全性。

首先,如果您使用表别名,您可以减少$wpdb多次引用的需要,并且它可以使更复杂的查询更具可读性(例如,如果您在不同的键上多次加入元表)。

更重要的是,您应该使用$wpdb->prepare()转义 SQL - 将变量插入语句中要求进行 SQL 注入。BETWEEN利用和DATE_ADD为您的条款可能也很有意义WHERE- 并非所有月份都有 31 天。如果您确实想传递开始和结束日期,您仍应%s在 SQL 中用作占位符并用于prepare()填充它。

global $wdbp;

$sql = <<<SQL
    SELECT votes.meta_value, c.comment_ID, c.comment_date, c.user_id, c.comment_content, c.comment_author
    FROM {$wpdb->comments} c
    JOIN {$wpdb->commentmeta} votes 
        ON votes.comment_id = c.comment_ID AND votes.meta_key = '_commentsvote'
    WHERE
        c.comment_date BETWEEN %s AND DATE_ADD(%s, INTERVAL 1 MONTH)
    ORDER BY CONVERT(votes.meta_value, SIGNED)
SQL;

$date = "{$current_year}-{$current_month}-01";
$query = $wpdb->prepare( $sql, $date, $date );
$results = $wpdb->get_results( $query );
于 2013-04-18T23:19:50.203 回答