我有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 |
我真的无法想象查询,所以有人可以帮助我进行查询吗?谢谢您的帮助。
答案 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 ;
在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;
感谢@LukStorms将查询改写回SQLSERVER