在基于其他表的“选择”中更改列名

时间:2019-12-17 09:36:42

标签: sql sql-server

我有2张桌子

DeductList

| DeID  | DeName | Deducts|
|   1   |  Late  |  $2.0  |
|   2   | No_IN  |  $1.0  |
|   3   | No_OUT |  $1.0  |

在DeductList表中,DeName是变量

TransList

|TransID| TransDate  | EmpID | Deduct1 | Deduct2 | Deduct3 |
|   1   | 2019-12-01 |   20  |   $2.0  |   $0.0  |  $0.0   |
|   2   | 2019-12-02 |   27  |   $0.0  |   $1.0  |  $0.0   |
|   3   | 2019-12-03 |   25  |   $0.0  |   $0.0  |  $0.0   |

在TransList表中,我已经有3列来存储基于DeID的Deducts值

现在我要选择TransList表并与DeductList表一起加入,所以结果是

具有Deduct1,Deduct2,Deduct3的

TransList表列名已更改为基于DeID的DeName。 当Deduct1然后用DeID 1命名,Deduct2用DeID2命名,依此类推。

当使用JOIN选择TransList Table到DeductList表时,这是我想要的结果:

|TransID| TransDate  | EmpID |  Late   |  No_IN  |  No_OUT |
|   1   | 2019-12-01 |   20  |   $2.0  |   $0.0  |  $0.0   |
|   2   | 2019-12-02 |   27  |   $0.0  |   $1.0  |  $0.0   |
|   3   | 2019-12-03 |   25  |   $0.0  |   $0.0  |  $0.0   |

我真的无法想象查询,所以有人可以帮助我进行查询吗?谢谢您的帮助。

2 个答案:

答案 0 :(得分:1)

您将需要动态sql以基于DeductList表添加列别名。

例如:

DECLARE @DynSql NVARCHAR(MAX);
DECLARE @Cols NVARCHAR(MAX);

SET @Cols = 'TransID, TransDate, EmpID ';

SELECT @Cols = CONCAT(@Cols,char(10),', Deduct',DeID,' AS ',QUOTENAME(DeName))
FROM DeductList 
WHERE DeID IN (1,2,3);

SET @DynSql = 'SELECT '
      + @Cols + char(10)
      + 'FROM TransList';

-- select @DynSql as DynSql;
EXECUTE sp_executesql @DynSql;

将运行以下SQL:

SELECT TransID, TransDate, EmpID 
, Deduct1 AS [Late]
, Deduct2 AS [No_IN]
, Deduct3 AS [No_OUT]
FROM TransList

答案 1 :(得分:0)

我不确定如何将其转换为SQL server查询,但是在Oracle中我可以使用recursion并达到所示结果。请参阅下文,并采用内联逻辑。请求SQL Server发烧友实施相同的逻辑。

ORACLE中:

--Dataset Preparation
With tab (DeID,Dename) as (Select 1, 'Late' from dual
                           UNION ALL
                           Select 2, 'No_IN' from dual
                           UNION ALL
                           Select 3, 'No_OUT' from dual
                           ),
tab2(TransID ,TransDate,EmpID ,Deduct1,Deduct2,Deduct3) as (
                         Select 1,date '2019-12-01',20,'$2.0','$0.0','$0.0' from dual
                         UNION ALL
                         Select 2,date '2019-12-02',27,'$0.0','$1.0','$0.0' from dual
                         UNION ALL
                         Select 3,date '2019-12-03',25,'$0.0','$0.0','$0.0' from dual
                        ),
--Dataset Preparation End
    tab3 as (   --Joining 2 tables to fetch all records & Converting the row to columns
                SELECT *
                FROM tab 
                INNER JOIN tab2
                ON tab.deid   = tab2.transid                
                PIVOT ( MIN(1)
                    FOR dename
                    IN ( 'Late' as late,
                    'No_IN' as No_IN,
                    'No_OUT' as NO_OUT )
                )                
                )    
--Final Query to display the required result.             
Select  t.deid, 
        t.transdate,
        t.empid,
        case  when t.Late is null then t.Deduct1  else t.Deduct1 end Late ,
        case  when t.No_IN is null then t.Deduct2 else t.Deduct2 end No_IN,
        case  when t.No_OUT is null then t.Deduct3 else t.Deduct3 end No_OUT
from tab3 t  ;           

DEMO

SQLSERVER

WITH tab AS
(
  SELECT * FROM DeductList
)
, tab2 AS
(
  SELECT * FROM TransList
)
, tab3 as
( --Joining 2 tables to fetch all records            
  SELECT *
  FROM tab 
  INNER JOIN tab2
  ON tab.deid = tab2.transid
  PIVOT ( 
    MIN(TransID)
    FOR dename IN ([Late], [No_IN], [No_OUT])
  ) pvt
)
--Final Query to display the required result.             
Select 
 t.deid, t.transdate, t.empid,
 case when t.Late is null then t.Deduct1 else t.Late end Late ,
 case when t.No_IN is null then t.Deduct2 else t.No_IN end No_IN,
 case  when t.No_OUT is null then t.Deduct3 else t.No_OUT end No_OUT
from tab3 t;           

SQLSERVER DEMO

感谢@LukStorms将查询改写回SQLSERVER