【问题标题】:How can I page through distinct filtered results?如何分页浏览不同的过滤结果?
【发布时间】:2013-05-22 16:41:38
【问题描述】:

我有以下疑问:

SELECT DISTINCT TOP 20 
    f.id_service as f_id_service,
    f.id_city as f_id_city,
    f.name as f_name,
    f.address as f_address,
    f.business as f_business,
    f.web as f_web,
    f.phone as f_phone,
    f.id_firm as f_id_firm
FROM
    Firm f
        left join
    Price p ON p.id_service = f.id_service
        AND p.id_city = f.id_city
        AND p.id_firm = f.id_firm
WHERE
    f.blocked = '0'
        AND (f.name LIKE 'авто%'
        OR f.phone LIKE 'авто%')
        AND (f.phone != '' OR f.address != '')
        AND f.id_city = '73041'
        AND f.dogovor = '1'
ORDER BY f.name ASC

此查询显示唯一 f.name 的前 20 行

当我需要选择具有唯一 f.name 的下 20 行时,我使用下一个查询:

SELECT DISTINCT TOP 20
    f.id_service AS f_id_service,
    f.id_city AS f_id_city,
    f.name AS f_name,
    f.address AS f_address,
    f.business AS f_business,
    f.web AS f_web,
    f.phone AS f_phone,
    f.id_firm AS f_id_firm
FROM
    Firm f
        LEFT JOIN
    Price p ON p.id_service = f.id_service
        AND p.id_city = f.id_city
        AND p.id_firm = f.id_firm
WHERE
    f.name NOT IN (SELECT DISTINCT TOP 20
            f.name
        FROM
            Firm f
        WHERE
            f.blocked = '0'
                AND (f.name LIKE '????%'
                OR f.phone LIKE '????%')
                AND (f.phone != '' OR f.address != '')
                AND f.id_city = '73041'
        ORDER BY f.name ASC)
        AND f.dogovor = '1'
        AND f.blocked = '0'
        AND (f.name LIKE '????%'
        OR f.phone LIKE '????%')
        AND (f.phone != '' OR f.address != '')
        AND f.id_city = '73041'
        AND f.dogovor = '1'
ORDER BY f.name ASC

但我看到,在最后一个查询中,我从第一个查询中查询了具有唯一 f.name 的选择行。

例如:

结果第一个查询(选择 TOP 20 行):

结果第二个查询(选择 NEXT TOP 20 行):

如何在第二张图片中看到第二个查询具有来自第一张图片的行(结果是第一个查询)。

请告诉我错误在哪里以及如何写正确?

【问题讨论】:

  • 嘿,在子查询中更改Firm表的别名,然后尝试
  • OFFSET (in MySQL - LIMIT) 只有在 SQL Server 2012 中。
  • @Devart 没有意识到这一点。谢谢提供信息。删除,因为我的解决方案没用。

标签: sql sql-server sql-server-2008


【解决方案1】:

试试这个 -

SELECT DISTINCT TOP 20 
    f.id_service AS f_id_service, 
    f.id_city AS f_id_city, 
    f.name AS f_name, 
    f.[address] AS f_address, 
    f.business AS f_business, 
    f.web AS f_web, 
    f.phone AS f_phone, 
    f.id_firm AS f_id_firm 
FROM dbo.Firm f
WHERE f.blocked = '0' 
    AND (f.name LIKE 'авто%' OR f.phone LIKE 'авто%') 
    AND f.phone + f.[address] != ''
    AND f.id_city='73041' 
    AND f.dogovor='1' 
ORDER BY f.name


SELECT *
FROM (
    SELECT DISTINCT 
        f.id_service AS f_id_service, 
        f.id_city AS f_id_city, 
        f.name AS f_name, 
        f.[address] AS f_address, 
        f.business AS f_business, 
        f.web AS f_web, 
        f.phone AS f_phone, 
        f.id_firm AS f_id_firm,
        row_id = ROW_NUMBER() OVER (ORDER BY f.name)
    FROM dbo.Firm f
    WHERE f.blocked = '0' 
        AND (f.name LIKE 'авто%' OR f.phone LIKE 'авто%') 
        AND f.phone + f.[address] != ''
        AND f.id_city='73041' 
        AND f.dogovor='1' 
) d
WHERE d.row_id BETWEEN 21 AND 40

【讨论】:

  • 也不需要LEFT JOIN Price p
【解决方案2】:

您使用的是哪种排序规则?也许这就是为什么您的字符串没有被排除在外的原因 'where f.name not in' 子句

当您选择似乎是表的 ID 时,您可以不使用“Distinct”,这将允许您按 ID 过滤掉前 20 条记录。

在哪里 f.id_service 不在( SELECT TOP 20 f.id_service FROM Firm f WHERE f.blocked='0' ...

【讨论】:

  • 不,我不能使用 id,因为 hi 不存在(id_serveice 不使用)
  • 我认为首先要检查 Ted 的建议 - 在 not in 子句中添加 'dogovor = 1' 看看是否可行。
【解决方案3】:

首先,这可能是语言障碍,但让我们明确一点,您的第一个查询不会显示唯一的 f.name 而是所有列的唯一组合。

另外,以这种方式使用 TOP 和 DISTINCT 是一个非常糟糕的主意。无法确保每次都能获得相同的结果。

最后你的 NOT IN 子句不见了AND f.dogovor='1'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-02
    • 2019-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多