在一个查询中使用 distinct 、 Case 和 order by

Using distinct , Case and order by in one query

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

另外,并非所有手机号码的格式都正确,因此我使用大小写来设置号码的格式。

最后我想获取最新的 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
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 

改为使用 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