【问题标题】:Using Inner Join on Comma-Separated Values in Stored Procedure在存储过程中对逗号分隔值使用内连接
【发布时间】:2013-03-05 17:52:30
【问题描述】:

我有一张表UserMaster 如下...(仅显示必填列)

UserID UserName EmailID
---------------------------------
1000   amol     amol@gmail.com
1001   mahesh   mahesh@gmail.com
1002   saurabh  saurabh@gmail.com
1003   nitesh   nitesh@gmail.com

另一个表MessageHistory(仅显示必填列)

MsgCode From  To
-----------------------------
MSG001  1000  1001,1002,1003
MSG002  1001  1000,1002,1003

我将UserIds 存储在FromTo 列中...

我正在尝试创建一个存储过程来显示特定消息代码的Email History

Create Procedure proc_GetMessageHistory
        @MsgCode varchar(50)
        as
        Begin
           Select * From MessageHistory Where MsgCode=@MsgCode 
        End

结果如上图MessageHistory 表所示...但我想显示相应的UserEmailIDs 而不是UserID(例如'amol@gmail.com' 而不是1000)...

如何在存储过程中做到这一点?在这种情况下,我如何特别使用逗号分隔值的内连接?请帮忙...谢谢

【问题讨论】:

  • 不要使用逗号分隔的值 - 这是糟糕的设计,而且总是一团糟,而且使用起来很糟糕。您需要使用 正确规范化 数据库表 - 然后 JOIN 将完全没有问题...
  • 是的,我同意..这将是改变数据库结构的最终解决方案......但是如果不这样做就没有办法实现这一点吗?
  • 有一些可怕的、疯狂的乱七八糟的黑客行为——不过我宁愿不去想那些......(颤抖)
  • 你需要实现 string.Split 作为 UDF 的等价物,加入它的输出,然后加入到 UserMaster。你可以这样做,但它会很慢。
  • 你可以像this answer一样这样做

标签: sql-server database sql-server-2008 stored-procedures inner-join


【解决方案1】:

正如大家已经注意到的那样,这绝不应该是任何形式的永久解决方案,因为它永远不会以有效的方式执行。此外,这种非规范化结构可能存在许多问题。那就是……

每封邮件的电子邮件地址列表,即每行一个收件人:

select m.MsgCode
  , sender = s.EmailID
  , recipient = u.EmailID
from MessageHistory m
  inner join UserMaster s on m.[From] = s.UserID
  inner join UserMaster u on charindex(cast(u.UserID as varchar), m.[To]) > 0

SQL Fiddle with demo.

邮件列表,以逗号分隔的电子邮件地址列表,每行一封邮件:

with emails as
(
  select m.MsgCode
    , recipient = u.EmailID
  from MessageHistory m
    inner join UserMaster u on charindex(cast(u.UserID as varchar), m.[To]) > 0
)
select m.MsgCode
  , [From] = u.EmailID
  , [To] = stuff
    (
      (
        select ',' + recipient
        from emails e
        where m.MsgCode = e.MsgCode
        for xml path('')
      )
      , 1
      , 1
      , ''
    )
from MessageHistory m
  inner join UserMaster u on m.[From] = u.UserID

SQL Fiddle with demo.

【讨论】:

  • 在上述 cmets 之后,我改变了 DB 的结构......虽然我会尝试理解和实现这段代码......它对我来说是新的学习......谢谢你的巨大努力.. .+1 :)
猜你喜欢
  • 2013-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多