创建sql函数(列类型X)

时间:2017-06-08 15:26:35

标签: sql function tsql stored-procedures

创建sql函数(Column typeX)

喜 我有这张表:

  autoID   |    id   |    name   |    age    |   Tel
------------------------------------------
      1    |    1   |   Frank   |    40     |   null
      2    |    1   |   null    |    50     |   7834xx
      3    |    1   |   Alex    |    null   |   null
      4    |    1   |   null    |    20     |   null
      5    |    2   |   James   |    null   |   4100xx
      6    |    3   |   jan     |    24     |   null
      7    |    3   |   null    |    null   |   4100xx

我对select的查询:

SELECT TOP 10
(SELECT top(1) name FROM test1 where id=1 and name is not null order by autoID desc) as name ,(SELECT top(1) age FROM test1 where id=1 and age is not null order by autoID desc) as Age ,(SELECT top(1) Tel 
FROM test1 
where id=1 and Tel 

不是autoID desc的空订单)作为Telephon FROM [dbo]。[test1] group by id

结果:

  autoID   |    id   |   name    |    age    |   Tel
------------------------------------------
      1    |    1    |   Alex    |    20     |  7834xx

我需要创建这样的函数:

CREATE FUNCTION TestSchema.MyfunctinX(@ColumnX @ColumnX.type)
RETURNS @ColumnX.type
AS
BEGIN
    DECLARE @value @ColumnX.type
    SELECT  top 1 @value from @ColumnX where @value is not null order by @autoID desc
    RETURN @value
END;
GO

对于我的选择查询,请使用Short:

Select Id, MyfunctinX(name) as [Name], MyfunctinX(age) as Age, MyfunctinX(Tel)
as Tel from yourtable Group by Id

有办法做到这一点吗?

1 个答案:

答案 0 :(得分:0)

您的结构效率不高。您可能更适合使用EAV结构(实体属性值)

示例

Select A.ID
      ,Name = [dbo].[MyFunction] (A.ID,'Name')
      ,Age  = [dbo].[MyFunction] (A.ID,'Age')
      ,Tel  = [dbo].[MyFunction] (A.ID,'Tel')
 From  (Select Distinct ID From YourTable ) A

<强>返回

ID  Name    Age     Tel
1   Alex    20      7834xx
2   James   NULL    4100xx
3   jan     24      4100xx

UDF

CREATE FUNCTION [dbo].[MyFunction] (@ID int,@Field varchar(100))
Returns varchar(max)
As
Begin
Return (  

Select Top 1 with ties Value
 From (Select XMLData = cast((Select * from YourTable where ID=@ID For XML RAW) as xml)) A
 Cross Apply (
                Select autoID = r.value('@autoID','int')
                      ,Item   = attr.value('local-name(.)','varchar(100)')
                      ,Value  = attr.value('.','varchar(max)') 
                 From  A.XMLData.nodes('/row') as A(r)
                 Cross Apply A.r.nodes('./@*') AS B(attr)
                 Where attr.value('local-name(.)','varchar(100)') not in ('autoID')
                   and attr.value('local-name(.)','varchar(100)')= @Field
             ) B
  Order By Row_Number() over (Partition By Item Order By autoID Desc)
)
End