如果无法在WHERE中使用ROW_NUMBER(),如何查找重复的行?

时间:2019-05-21 14:43:45

标签: sql sql-server

此查询获取重复的行。在删除重复项之前,我将使用此查询更新对重复项的引用。

add_action( 'woocommerce_order_item_meta_start', 'add_download_links_to_thank_you_page', 10, 3 );
function add_download_links_to_thank_you_page( $item_id, $item, $order ) {
    // Set below your product attribute taxonomy (always starts with "pa_")
    $taxonomy = 'pa_location';

    // On email notifications
    if ( ! is_wc_endpoint_url() && $item->is_type('line_item') ) {
        $product    = $item->get_product();
        $label_name = get_taxonomy( $taxonomy )->labels->singular_name;

        if ( $term_names = $product->get_attribute( $taxonomy ) ) {
            echo '<br/><small>' . $label_name . ': ' . nl2br( $term_names ) . '</small>';
        }
    }
}

woocommerce_order_item_meta_end行无效,给了我SELECT TOP 350000 itmopt_pk, item_fk, option_fk, ROW_NUMBER()OVER(PARTITION BY item_fk, option_fk ORDER BY item_fk ASC, option_fk ASC) AS RN FROM item_options WHERE RN > 1 GROUP BY itmopt_pk, item_fk, option_fk ORDER BY RN DESC

尝试使用AND RN > 1会给我Invalid column name 'RN'

我正在使用sqlsrv。

如何仅返回AND ROW_NUMBER()OVER(PARTITION BY item_fk, option_fk ORDER BY item_fk ASC, option_fk ASC) > 1的行?

2 个答案:

答案 0 :(得分:3)

您不理解消息的哪一部分? where中不允许使用窗口函数。在相应的SELECT中也没有定义列别名。使用子查询:

SELECT TOP 350000 itmopt_pk, item_fk, option_fk
FROM (SELECT itmopt_pk, item_fk, option_fk,
             ROW_NUMBER() OVER (PARTITION BY item_fk, option_fk ORDER BY item_fk ASC, option_fk ASC) AS RN
      FROM item_options
     ) io
WHERE RN > 1
GROUP BY itmopt_pk, item_fk, option_fk
ORDER BY RN DESC;

此查询似乎很奇怪。我想知道是否还有另一种表达您想要的方式。

答案 1 :(得分:2)

您不能在WHERE子句中使用列别名和Window函数。您可以使用CTE或子查询。

选项1:公用表表达式:

WITH cte_query AS 
(
SELECT itmopt_pk, item_fk, option_fk,
ROW_NUMBER()OVER(PARTITION BY item_fk, option_fk ORDER BY item_fk ASC, option_fk ASC) AS RN
FROM item_options
GROUP BY itmopt_pk, item_fk, option_fk
)
SELECT itmopt_pk, item_fk, option_fk, RN
FROM cte_query
WHERE RN > 1

选项2:子查询:

SELECT itmopt_pk, item_fk, option_fk, RN
FROM 
(
SELECT  itmopt_pk, item_fk, option_fk,
ROW_NUMBER()OVER(PARTITION BY item_fk, option_fk ORDER BY item_fk ASC, option_fk ASC) AS RN
FROM item_options
GROUP BY itmopt_pk, item_fk, option_fk
) A
WHERE RN > 1