Sql server 2005 从数据库中的不同表获取信息
我有两张桌子:Sql server 2005 从数据库中的不同表获取信息,sql-server-2005,tsql,Sql Server 2005,Tsql,我有两张桌子: User --------------------- id primary key name varchar mobile varchar 样本数据:(1,airtel,'98874562169852659888523695874') 样本数据:(1,John Doe,9887456321) 我想根据移动字段值从第一个表中搜索客户机名称 如果移动字段有值(98874562169853269888523695874),那么我如何知道
User
---------------------
id primary key
name varchar
mobile varchar
样本数据:(1,airtel,'98874562169852659888523695874')
样本数据:(1,John Doe,9887456321)
我想根据移动字段值从第一个表中搜索客户机名称
如果移动字段有值
(98874562169853269888523695874)
,那么我如何知道特定移动电话号码属于哪个客户端名称?在您的客户端
表和另一个表之间必须有一个匹配列。从你的描述中不清楚那列是什么。根据您所说的,我相信您的模式如下所示:
Create Table MobileNumbers
(
Id ... not null Primary Key
, Name varchar(??) not null
, Mobile varchar(??) not null
)
Create Table Client
(
Id ... not null Primary Key
, ClientName varchar(??) not null
, MobileNo varchar(??) not null
)
假设Client.Mobile与MobileNumbers.Name匹配,我们有:
Select ...
From Client
Join MobileNumbers
On MobileNumbers.MobileNo = Client.Mobile
Where Client.Mobile In('9887456321','6985326598','88523695874')
在这个结构中,我假设每个移动值都包含一个数字,而不是逗号分隔的数字列表。如果实际情况是单个单元格可以包含多个值(请编辑您的原始帖子),那么正如Martin Smith所提到的,您需要规范化数据
编辑
考虑到OP的修订版,根本问题是在一列中有多个值。正确的解决方案是将手机号码标准化为第二个表:
Create Table UserMobileNumber
(
UserId ... not null References User ( Id )
, Carrier varchar(??) not null
, Mobile varchar(??) not null
, Constraint UC_UserMobileNumber Unique ( Mobile )
)
那么解决方案就变得微不足道了:
Select ...
From User
Join UserMobileNumber
On UserMobileNumber.UserId = User.Id
Where UserMobileNumber.Mobile In('9887456321','6985326598','88523695874')
但是,在此期间,您需要的是一个拆分函数:
Create Function dbo.udf_Split
(
@DelimitedList nvarchar(max)
, @Delimiter nvarchar(2) = ','
)
Returns Table
As
Return
(
With CorrectedList As
(
Select Case When Left(@DelimitedList, Len(@Delimiter)) <> @Delimiter Then @Delimiter Else '' End
+ @DelimitedList
+ Case When Right(@DelimitedList, Len(@Delimiter)) <> @Delimiter Then @Delimiter Else '' End
As List
, Len(@Delimiter) As DelimiterLen
)
, Numbers As
(
Select TOP (Len(@DelimitedList) + 2) Row_Number() Over ( Order By c1.object_id ) As Value
From sys.columns As c1
Cross Join sys.columns As c2
)
Select CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen As Position
, Substring (
CL.List
, CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen
, CharIndex(@Delimiter, CL.list, N.Value + 1)
- ( CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen )
) As Value
From CorrectedList As CL
Cross Join Numbers As N
Where N.Value < Len(CL.List)
And Substring(CL.List, N.Value, CL.DelimiterLen) = @Delimiter
)
单个移动值可以包含三个逗号分隔的不同数字,还是有三行有三个数字?谢谢George。编辑之后,事情看起来更清楚了@进行一些重组显然是顺理成章的。用户、客户端和手机之间的关系是什么?一个客户端是否只有一个手机?如果是这样,是否意味着用户表中始终只有一条对应的记录?
Create Function dbo.udf_Split
(
@DelimitedList nvarchar(max)
, @Delimiter nvarchar(2) = ','
)
Returns Table
As
Return
(
With CorrectedList As
(
Select Case When Left(@DelimitedList, Len(@Delimiter)) <> @Delimiter Then @Delimiter Else '' End
+ @DelimitedList
+ Case When Right(@DelimitedList, Len(@Delimiter)) <> @Delimiter Then @Delimiter Else '' End
As List
, Len(@Delimiter) As DelimiterLen
)
, Numbers As
(
Select TOP (Len(@DelimitedList) + 2) Row_Number() Over ( Order By c1.object_id ) As Value
From sys.columns As c1
Cross Join sys.columns As c2
)
Select CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen As Position
, Substring (
CL.List
, CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen
, CharIndex(@Delimiter, CL.list, N.Value + 1)
- ( CharIndex(@Delimiter, CL.list, N.Value) + CL.DelimiterLen )
) As Value
From CorrectedList As CL
Cross Join Numbers As N
Where N.Value < Len(CL.List)
And Substring(CL.List, N.Value, CL.DelimiterLen) = @Delimiter
)
Select ...
From User
Outer Apply dbo.Split( User.Mobile ) As M
Join Client
On Client.MobileNo = M.Value
Where M.Value In('9887456321','6985326598','88523695874')