sql查询FULL OUTER,在WHERE中的情况

时间:2017-01-18 23:30:09

标签: sql sql-server

我有一个要求,我想从表CLIENT中提取所有列,只从表CLIPHONE中提取电话号码。对于电话号码,一些客户在CLIPHONE中列出了多个电话号码,但我只想要一个电话号码。因此,如果客户端在描述中列出了“单元”或“移动”,那么我想要具有最小序列值的数字。如果未列出单元格或移动设备,则我希望序列设置为1

示例:在CLIPHONE中

Joey A - clientid = 25,sourceloc = 1,phone = 1234567890,description = home,sequence = 1

Joey A - clientid = 25,sourceloc = 1,phone = 0987654321,description = cell,sequence = 2

Joey A - clientid = 25,sourceloc = 1,phone = 1111111111,description = mobile,sequence = 3

然后,当我运行查询时,我希望电话号码0987654321显示来自CLIENT的列,因为它包含单词'cell',并且序列3的序列低于其中的'mobile'。如果序列#2的电话在描述中有单词office,那么我希望序列3显示在查询结果中,因为它现在是最低的,其中包含“cell”或“mobile”一词

如果序列2和3都改为'other',那么我希望序列1出现,因为没有其他序列有'cell'或'mobile'。

使用我的查询我收到此错误: Msg 147,Level 15,State 1,Line 5 聚合可能不会出现在WHERE子句中,除非它位于HAVING子句或选择列表中包含的子查询中,并且要聚合的列是外部引用。

SELECT DISTINCT TOP 1000 cp.phone, c.*
FROM CLIENT C
FULL OUTER JOIN CLIPHONE CP
ON c.clientid = cp.clientid AND c.sourceloc = cp.sourceloc
WHERE cp.sequence = CASE WHEN (description LIKE '%mobile%' OR description LIKE '%cell%') THEN min(sequence) ELSE 1 END 
ORDER BY sourceloc, clientid

以下是我的表格:

CLIPHONE

CLIENT

1 个答案:

答案 0 :(得分:0)

with phones as (
    select *,
        row_number over (
            partition by cp.clientid
            order by
                case when cp.description in ('cell', 'mobile') then 1 else 2 end,
                cp.sequence
        ) as rnk
    from CLIENT c inner join CLIPHONE cp
        on cp.clientid = c.clientid and cp.sourceloc = c.sourceloc
)
select * from phones where rnk = 1;

我怀疑你真的需要一个完整的外部联接。即使您将其添加回来,查询应该仍然有效。