【问题标题】:SQL Server : multiply column with alias name in select list [duplicate]SQL Server:在选择列表中将列与别名相乘[重复]
【发布时间】:2019-01-31 00:46:34
【问题描述】:

我的查询中有一个选择列表,如下所示:

SELECT 
    COUNT(*) OVER () AS TotalRowsFound,
    MIN(t.Title) AS Title,
    t.ItemID, ' + @selectedColumn + ' as SelectedColumnSales ' + ', 
    t.CurrentPrice,
    (t.CurrentPrice * t.SelectedColumnSales) as TotalRevenuePerItem
FROM 
    dbo.SearchedUserItems t

我遇到问题的查询部分如下:

  (t.CurrentPrice * t.SelectedColumnSales) as TotalRevenuePerItem

在选择列表中...“SelectedColumnSales”可以是不同的列,具体取决于我传递给查询的内容,如下所示:

DECLARE @selectedColumn NVARCHAR(500)

    IF(@SelectedRange=7)
       SET @selectedColumn = 't.SevenDaySales'
    ELSE IF (@SelectedRange=14)
       SET @selectedColumn='t.FourteenDaySales'
    ELSE IF (@SelectedRange=21)
       SET @selectedColumn='t.TwentyOneDaySales'
    ELSE IF (@SelectedRange=30)
       SET @selectedColumn='t.ThirtyDaySales'

现在要获得每个项目列的收入,我需要像上面那样将这两个相乘,但是查询会抛出这个错误:

内部异常:SqlException:列名“SelectedColumnSales”无效。

如何在选择列表中将动态列与静态列相乘?

谁能帮帮我?

【问题讨论】:

  • 将您的查询包装在一个派生表中,然后您可以引用它之外的那些列。

标签: sql sql-server sql-server-2008 select multiplication


【解决方案1】:

或许通过用户选择的INDEX,使用CHOOSE()

假设:

Item               Index
SevenDaySales      0
FourteenDaySales   1
TwentyOneDaySales  2
ThirtyDaySales     3

那你就可以了

SELECT COUNT(*) OVER () AS TotalRowsFound
      ,MIN(t.Title) AS Title
      ,t.ItemID
      ,choose(@Index+1,t.SevenDaySales,t.FourteenDaySales,t.TwentyOneDaySales,t.ThirtyDaySales) as SelectedColumnSales  
      ,t.CurrentPrice
      ,(t.CurrentPrice * choose(@Index+1,t.SevenDaySales,t.FourteenDaySales,t.TwentyOneDaySales,t.ThirtyDaySales)) as TotalRevenuePerItem
 FROM  dbo.SearchedUserItems t

如果你不想传递索引,而不是 @Index+1 ,你可以 @SelectedRange/7

【讨论】:

    【解决方案2】:

    如果您正在编写一个动态查询,看起来就像您一样,您可以将变量放入您的方程式中

     declare @sql nvarchar(max)
     set @sql = 'select 
        COUNT(*) OVER () AS TotalRowsFound,
            MIN(t.Title) AS Title
            , t.ItemID
            ,' + @selectedColumn + ' as SelectedColumnSales ' + 
            ', t.CurrentPrice
             , (t.CurrentPrice * ' + @selectedColumn + ') as TotalRevenuePerItem
    
        FROM 
            dbo.SearchedUserItems t'
    exec(@sql)
    

    【讨论】:

    • 我会将QUOTENAME() 放在列名周围,只是为了增加一点针对 SQL 注入的额外安全性。为了获得最佳实践/连续性,即使您没有要传递的强类型参数,我也会始终使用 sp_executesql
    【解决方案3】:

    将您的查询包装在派生表中,然后您可以引用它之外的那些列:

    select dt.TotalRowsFound, dt.Title, ... ,
          (dt.CurrentPrice * dt.SelectedColumnSales) as TotalRevenuePerItem
    from
    (
      SELECT 
        COUNT(*) OVER () AS TotalRowsFound,
            MIN(t.Title) AS Title
            , t.ItemID
            ,' + @selectedColumn + ' as SelectedColumnSales ' + 
            ', t.CurrentPrice
        FROM 
            dbo.SearchedUserItems t
    ) dt
    

    【讨论】:

      【解决方案4】:

      您可以尝试使用 case when 子句直接在查询中使用登录而不是字符串

       SELECT 
          COUNT(*) OVER () AS TotalRowsFound,
              MIN(t.Title) AS Title
              , t.ItemID
              , case when @SelectedRange=7 then t.SevenDaySales 
                    when @SelectedRange=14 then t.FourteenDaySales
                    when @SelectedRange=21 then t.TwentyOneDaySales
                    when (@SelectedRange=30 then t.ThirtyDaySales end 
               as SelectedColumnSales  
              , t.CurrentPrice
               , (t.CurrentPrice * t.SelectedColumnSales) as TotalRevenuePerItem
      
          FROM 
              dbo.SearchedUserItems t
      

      【讨论】:

        猜你喜欢
        • 2015-05-06
        • 2017-06-04
        • 2022-09-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多