【问题标题】:Using distinct , Case and order by in one query在一个查询中使用 distinct 、 Case 和 order by
【发布时间】:2019-11-21 05:49:11
【问题描述】:

我需要从数据库中检索没有重复的用户手机号码,所以我使用 distinct 关键字来做到这一点。

此外,并非所有手机号码的格式都很好,所以我使用 Case 来格式化号码。

最后我想获取最新的 500 个手机号码,所以我想通过 Order by ID desc 进行排序,但它显示了

ORDER BY items must appear in the select list if SELECT DISTINCT is specified.

下面是我的查询

 select distinct top 500  case 

                     when len(PhoneNumber) = 13 And phoneNumber  like '+311%' then replace(PhoneNumber, '+311', '0')
                     when len(PhoneNumber) = 13 And phoneNumber  like '311-%' then replace(PhoneNumber, '311-', '0')

                     when len(PhoneNumber) = 13 And phoneNumber  like '0311%' then stuff(PhoneNumber, 1, 4 , 0 )

                     when len(PhoneNumber) = 14 And phoneNumber  like '00311%'then stuff(PhoneNumber, 1, 5 ,'0')
                     when len(PhoneNumber) = 14 And phoneNumber  like '00311%' then stuff(PhoneNumber, 1, 4 ,'0')


                     when len(PhoneNumber) = 12 And phoneNumber  like '311%' then stuff(PhoneNumber, 1 , 3 , '0')
                     when len(PhoneNumber) = 12 then REPLACE (PhoneNumber, '-', '')

                     when len(PhoneNumber) = 11 And phoneNumber  like '00%' then Stuff(PhoneNumber, 1, 2 , '0')
                     else PhoneNumber
                end 


from users where  cityid = 1 and statusid = 1  and  (len(PhoneNumber) >= 10 And len(PhoneNumber) <= 14) 
and PhoneNumber not like '"%' and PhoneNumber not like '+311-%' and PhoneNumber not like '01%'
and PhoneNumber  like '0%'

Order by id 

更新

正如 Metal 所建议的,我正在使用 row_number() 并通过它进行分区给我一个手机号码,这是不正确的结果

select top 500000 Mobile
from 
    (select 
        row_number() over (partition by PhoneNumber order by id desc) rn,
        case 
        when len(PhoneNumber) = 13 And phoneNumber  like '+966%' then replace(PhoneNumber, '+966', '0')
        when len(PhoneNumber) = 13 And phoneNumber  like '966-%' then replace(PhoneNumber, '966-', '0')
        when len(PhoneNumber) = 13 And phoneNumber  like '0966%' then stuff(PhoneNumber, 1, 4 , 0 )
        when len(PhoneNumber) = 14 And phoneNumber  like '00966%'then stuff(PhoneNumber, 1, 5 ,'0')
        when len(PhoneNumber) = 14 And phoneNumber  like '0096%' then stuff(PhoneNumber, 1, 4 ,'0')
        when len(PhoneNumber) = 12 And phoneNumber  like '966%' then stuff(PhoneNumber, 1 , 3 , '0')
        when len(PhoneNumber) = 12 then REPLACE (PhoneNumber, '-', '')
        when len(PhoneNumber) = 11 And phoneNumber  like '00%' then Stuff(PhoneNumber, 1, 2 , '0')
        else PhoneNumber
        end  as Mobile
    from consigneeDetail 
    where  cityid = 1 and statusid = 1  and  (len(PhoneNumber) >= 10 And len(PhoneNumber) <= 14) 
            and PhoneNumber not like '"%' and PhoneNumber not like '+966-%' and PhoneNumber not like '01%'
            and PhoneNumber  like '0%') t1
where rn = 1

【问题讨论】:

    标签: mysql sql database case distinct


    【解决方案1】:

    改为使用subquery,然后使用row_number() 来获得不同的值。

    select top 500 t2.col1 from (
        select row_number() over (partition by t1.col1 order by id desc) rn, t1.col1
        from 
            (select         
                id,
                case 
                when len(PhoneNumber) = 13 And phoneNumber  like '+311%' then replace(PhoneNumber, '+311', '0')
                when len(PhoneNumber) = 13 And phoneNumber  like '311-%' then replace(PhoneNumber, '311-', '0')
                when len(PhoneNumber) = 13 And phoneNumber  like '0311%' then stuff(PhoneNumber, 1, 4 , 0 )
                when len(PhoneNumber) = 14 And phoneNumber  like '00311%'then stuff(PhoneNumber, 1, 5 ,'0')
                when len(PhoneNumber) = 14 And phoneNumber  like '00311%' then stuff(PhoneNumber, 1, 4 ,'0')
                when len(PhoneNumber) = 12 And phoneNumber  like '311%' then stuff(PhoneNumber, 1 , 3 , '0')
                when len(PhoneNumber) = 12 then REPLACE (PhoneNumber, '-', '')
                when len(PhoneNumber) = 11 And phoneNumber  like '00%' then Stuff(PhoneNumber, 1, 2 , '0')
                else PhoneNumber
                end  as col1
            from users 
            where  cityid = 1 and statusid = 1  and  (len(PhoneNumber) >= 10 And len(PhoneNumber) <= 14) 
                    and PhoneNumber not like '"%' and PhoneNumber not like '+311-%' and PhoneNumber not like '01%'
                    and PhoneNumber  like '0%') t1
        ) t2 
    where t2.rn = 1
    

    【讨论】:

    • @rav,忘记别名,再试一次
    • 我试过了,它只返回一条记录,不正确
    • rn = 1 是什么意思?以及为什么包含 t1?
    • 再试一次,它只是top X的替代品
    • 你摇滚!记录即将到来,但我如何确保它们是独一无二的?我有点担心
    【解决方案2】:
    SELECT DISTINCT phonenumber 
    FROM   (SELECT id, 
                   CASE 
                     WHEN Len(phonenumber) = 13 
                          AND phonenumber LIKE '+311%' THEN 
                     REPLACE(phonenumber, '+311', '0') 
                     WHEN Len(phonenumber) = 13 
                          AND phonenumber LIKE '311-%' THEN 
                     REPLACE(phonenumber, '311-', '0') 
                     WHEN Len(phonenumber) = 13 
                          AND phonenumber LIKE '0311%' THEN 
                     Stuff(phonenumber, 1, 4, 0) 
                     WHEN Len(phonenumber) = 14 
                          AND phonenumber LIKE '00311%'THEN 
                     Stuff(phonenumber, 1, 5, '0') 
                     WHEN Len(phonenumber) = 14 
                          AND phonenumber LIKE '00311%' THEN 
                     Stuff(phonenumber, 1, 4, '0') 
                     WHEN Len(phonenumber) = 12 
                          AND phonenumber LIKE '311%' THEN 
                     Stuff(phonenumber, 1, 3, '0') 
                     WHEN Len(phonenumber) = 12 THEN REPLACE (phonenumber, '-', '') 
                     WHEN Len(phonenumber) = 11 
                          AND phonenumber LIKE '00%' THEN 
                     Stuff(phonenumber, 1, 2, '0') 
                     ELSE phonenumber 
                   end AS phonenumber 
            FROM   users 
            WHERE  cityid = 1 
                   AND statusid = 1 
                   AND ( Len(phonenumber) >= 10 
                         AND Len(phonenumber) <= 14 ) 
                   AND phonenumber NOT LIKE '"%' 
                   AND phonenumber NOT LIKE '+311-%' 
                   AND phonenumber NOT LIKE '01%' 
                   AND phonenumber LIKE '0%' 
            ORDER  BY id) 
    LIMIT  500 
    

    【讨论】:

    • 我不想在选择语句中包含 id,因为这可能会给我一个重复的手机号码,一个用户可以有 2 条具有不同 id 和相同手机号码的记录,如果不同,它会考虑它是独一无二的,因为 id 不同
    • 使用子查询根据您的要求更新
    • @rav 你能查到吗?
    • 关键字“distinct”附近的语法不正确 关键字“Order”附近的语法不正确。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 2012-08-29
    • 2019-01-08
    • 2021-07-12
    • 1970-01-01
    • 2016-11-13
    相关资源
    最近更新 更多