【问题标题】:Create a view using SQL Server with repeating rows and new column使用带有重复行和新列的 SQL Server 创建视图
【发布时间】:2016-04-25 10:35:13
【问题描述】:

我有一个包含以下列的表格。

EVAL_ID    | GGRP_ID     | GOAL_ID 
1            1             1    
2            2             1
2            2             2
3            1             3

我想创建一个视图,其中包含另一个名为 GOAL_VERSION 的列,其值从 1 到 3。因此上表中的每一行都应针对不同的 GOAL_VERSION 数字重复 5 次。输出应该是这样的。

EVAL_ID    | GGRP_ID     | GOAL_ID    |GOAL_VERSION 
1            1             1            1
1            1             1            2
1            1             1            3
1            1             1            4
1            1             1            5
2            2             1            1
2            2             1            2
2            2             1            3
2            2             1            4
2            2             1            5

我该怎么做。帮我。谢谢。

【问题讨论】:

    标签: sql-server tsql view


    【解决方案1】:

    这是你要找的吗?

    DECLARE @tbl TABLE(EVAL_ID INT,GGRP_ID INT,GOAL_ID INT);
    INSERT INTO @tbl VALUES
     (1,1,1)   
    ,(2,2,1)
    ,(2,2,2)
    ,(3,1,3);
    
    SELECT tbl.*
          ,x.Nr
    FROM @tbl AS tbl
    CROSS JOIN (VALUES(1),(2),(3),(4),(5)) AS x(Nr)
    

    编辑:改变重复次数

    DECLARE @tbl TABLE(EVAL_ID INT,GGRP_ID INT,GOAL_ID INT);
    INSERT INTO @tbl VALUES
     (1,1,1)   
    ,(2,2,1)
    ,(2,2,2)
    ,(3,1,3);
    
    DECLARE @tblCountOfRep TABLE(CountOfRep INT);
    INSERT INTO @tblCountOfRep VALUES(3);
    
    SELECT tbl.*
          ,y.Nr
    FROM @tbl AS tbl
    CROSS JOIN (SELECT TOP (SELECT CountOfRep FROM @tblCountOfRep) * FROM(VALUES(1),(2),(3),(4),(5) /*add the max count here*/) AS x(Nr)) AS y 
    

    在这种情况下,我更喜欢 I 数字表...

    【讨论】:

    • 你可以缩短这个CROSS JOIN (VALUES(1),(2),(3),(4),(5)) AS x(Nr)
    • 列数不固定怎么办。这意味着每次调用视图时,我应该从另一个表中获取数字作为 MAX 值。
    • @jayz,抱歉,不明白...如果您的“正常”SELECT * FROM Somewhere 在 20 行中返回 X 列,CROSS JOIN 将再添加一列并返回 100 行,编号均来自1 到 5 ...`
    • 对不起。我的意思是如果每行重复的次数应该变化,就像它必须从另一个表的数据中收集一样(1-5 可能更改为 1-6 或 1-7)我该怎么办。那么 VALUES(1),(2),(3),(4),(5) 这应该是一个变量还是类似的东西?
    • 谢谢。这解决了我的问题。但我总是不得不提到一个上限。对吗?
    【解决方案2】:

    看看 CROSS JOIN。如果您制作的表格有一列包含您想要的 5 行,您只需 CROSS JOIN 即可获得您想要的结果。

    【讨论】:

      【解决方案3】:

      您可以使用CTECROSS APPLY 实现此目的:

      ;WITH CTE AS
      (
          SELECT 1 AS GOAL_VERSION
          UNION
          SELECT 2
          UNION
          SELECT 3
          UNION
          SELECT 4
          UNION
          SELECT 5
      )
      SELECT * FROM <your table>
      CROSS APPLY CTE
      

      【讨论】:

        【解决方案4】:

        使用 "with" (cte) 和 rank 子句来创建视图。

        【讨论】:

          【解决方案5】:

          如果您在 SQL 数据库中有一个数字表,您可以将您的表与数字表交叉连接以获取 1 到 5 之间的数字

          这是我的 SQL 解决方案,可满足您的要求

          select 
             goals.*, 
             n.i as GOAL_VERSION
          from goals, dbo.NumbersTable(1,5,1) n
          

          这是 cmets 中建议的带有“交叉连接”的修改版本

          select 
             goals.*, 
             n.i as GOAL_VERSION
          from goals
          cross join dbo.NumbersTable(1,5,1) n
          

          你可以实现,我使用了一个SQL表值函数SQL numbers table 请使用参考教程中给出的源代码创建该 SQL 函数 希望对你有帮助,

          【讨论】:

          • 而不是简单的“老式”加入逗号,最好使用CROSS JOIN...顺便说一句:我不是投票者...
          • 没问题 :) 我在帖子中实际上提到的是数字表的使用。有些人从主数据库 sys..spt_values 或任何其他资源中使用它。但是我发现为日期和数字表保留一个函数表非常方便..
          • 是的,数字表非常方便。我使用一个带有多个侧列(日索引、周索引...)的列来获得快速的日期时间计算方法
          猜你喜欢
          • 2023-03-22
          • 1970-01-01
          • 1970-01-01
          • 2014-01-20
          • 2015-04-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多