将列提取到其他表时更改SQL语句

时间:2014-01-31 19:40:37

标签: sql sql-server-2008

我们有一个跟踪客户问题的数据库。我的任务是添加一个“站点”选项卡,作为其中的一部分,我们从dbo.client表中提取了地址信息,并创建了一个新的dbo.address表。

我是SQL的新手,但是我已经设法通过修改存储过程来搞砸了。但是,我们有一个创建动态SQL语句的方法,因为它尝试从dbo.client表而不是新的dbo.address表中访问地址信息,显然不起作用。

本声明的一个可能的迭代如下:

select iclientid, 
    (select top 1 isstype.cistypdesc 
        from issue 
            inner join status on issue.istatusid = status.istatusid 
            left outer join priorty on issue.ipriortyid = priorty.ipriortyid 
            left outer join isstype on issue.iisstypeid = isstype.iisstypeid 
        where issue.iclientid = client.iclientid 
            and issue.istatusid <> 2 
        order by status.nrank desc, priorty.nrank desc, isstype.nrank desc) 
as cistypdesc,
    (select top 1 status.cstatdesc 
        from issue 
            inner join status on issue.istatusid = status.istatusid 
            left outer join priorty on issue.ipriortyid = priorty.ipriortyid 
            left outer join isstype on issue.iisstypeid = isstype.iisstypeid 
        where issue.iclientid = client.iclientid 
            and issue.istatusid <> 2 
        order by status.nrank desc, priorty.nrank desc, isstype.nrank desc) 
as cstatdesc,
    (select top 1 priorty.cpriority 
        from issue 
            inner join status on issue.istatusid = status.istatusid 
            left outer join priorty on issue.ipriortyid = priorty.ipriortyid 
            left outer join isstype on issue.iisstypeid = isstype.iisstypeid 
        where issue.iclientid = client.iclientid 
            and issue.istatusid <> 2 
        order by status.nrank desc, priorty.nrank desc, isstype.nrank desc) 
as cpriority,cname,ccity,cstateid,czip,isupplvlid 
from client 
where client.ccity like 'sea%' and client.isupplvlid <> 4

当我运行此操作时,我收到以下错误:

Msg 207, Level 16, State 1, Line 32
Invalid column name 'ccity'.
Msg 207, Level 16, State 1, Line 30
Invalid column name 'ccity'.
Msg 207, Level 16, State 1, Line 30
Invalid column name 'cstateid'.
Msg 207, Level 16, State 1, Line 30
Invalid column name 'czip'.

我可以删除对ccity,cstateid和czip的引用,使其执行没有错误,但是我得到的行多于我想要的,而不是我需要的所有信息。

一个有用的答案将显示我需要做些什么才能让它再次运行,因为我有一个dbo.address表(与address.iclientid = client.iclientid相匹配。有什么更有助于解释什么需要要做,所以我可以自己做。

我可以看到每个内部选择都从特定表中获取一条信息。我也知道INNER JOIN只返回匹配列的数据,而LEFT OUTER JOIN返回左表中与右列匹配的所有列。然而,当这些开始叠加时,我不确定它们是如何相互作用的。另外,当我拿出“where client.ccity like'sea%'”时,我得到了数千行而不是4行。如果我在括号中添加另一个命令,这会将它再次限制为4吗?

这个SQL语句只是我的基本理解。

1 个答案:

答案 0 :(得分:1)

您需要将client加入address,以便从两个表中获取过去仅在一个表中发生的信息。例如:

FROM dbo.client AS c 
INNER JOIN dbo.address AS a
ON a.iclientid = c.iclientid
WHERE a.ccity LIKE 'sea%' ...

您还应该考虑删除TOP (1)列表中的所有SELECT子查询 - 我也可以通过简单的连接来促进这些子查询;但可能是外连接,因为我不确定那里是否有1:0映射。也许:

SELECT
  c.iclientid,
  x.cistypdesc,
  x.cstatdesc,
  x.cpriority,
  c.cname,
  a.ccity,
  a.cstateid,
  a.czip,
  c.isupplvlid 
FROM dbo.client AS c
INNER JOIN dbo.address AS a
ON c.iclientid = a.iclientid
LEFT OUTER JOIN 
(
  SELECT iclientid, cistypdesc, cstatdesc, cpriority 
  FROM 
  (
    SELECT i.iclientid, i.cistypdesc, s.cstatdesc, p.cpriority,
      rn = ROW_NUMBER() OVER (PARTITION BY i.iclientid
         ORDER BY s.nrank DESC, p.nrank DESC, t.nrank DESC) 
     FROM dbo.issue
     INNER dbo.[status] AS s ON i.istatusid = s.istatusid 
     LEFT OUTER JOIN dbo.priorty AS p ON i.ipriortyid = p.ipriortyid 
     LEFT OUTER JOIN dbo.isstype AS t ON i.iisstypeid = t.iisstypeid 
     WHERE i.istatusid <> 2 
  ) AS y WHERE rn = 1
) AS x 
ON x.iclientid = c.iclientid
WHERE a.ccity LIKE 'sea%' AND c.isupplvlid <> 4;