SELECT 每个 ID 只有一个值 - SQL 服务器
SELECT Only one value per ID - SQL Server
我根本不知道这是否可行,我什至不确定如何 google。
我正在使用 SQL Server 2014。
现在我有一个 SP,它输出 table 数据,包括 MovementID、Vehicle、VehicleType 和 Total of sales。
但它将所有车辆 id 和车辆类型组合在一起。
我需要分开车辆,我可以。
问题是总数出现重复,或一式三份等。
那么,我怎样才能 select 每个 ID(示例中的 MovementID)只出现一次该列。
当然,我会继续努力,但如果有任何想法,我们将不胜感激。
[
您可以按 MovementID 对记录进行分区,然后生成 ROW_NUMBER for each row in the partition. Then, you can use IIF 以仅在行号为 1 时显示总数,即该行是分区中的第一行。它应该看起来像这样:
SELECT MovementID, VehicleID, VehicleType, IIF(rowno = 1, Total, NULL)
FROM
(
SELECT MovementID, VehicleID, VehicleType, Total,
ROW_NUMBER() OVER (PARTITION BY MovementID ORDER BY MovementID) AS rowno
FROM <WHAT_I_HAVE_NOW>
) tmp
您可以使用 LAG
查看上一行的值。
with q as (your query here)
select
movementid, vehicleid, vecicletype,
case when movementid = lag(movementid) over (order by movementid, vehicleid)
then null else total
end as total
from q
order by movementid, vehicleid;
您可以按照以下方式拆分和加入:
;with cte_vids as (
select * from #tblmove
cross apply udf_split( vehicleids, ',')
), cte_vtypes as (
select * from #tblmove
cross apply udf_split( vehicletypes, ',')
)
select cid.movementid, cid.[value] as vehichleid, cty.[value] as vehicletype,
case when cid.rown = 1 then cid.total else null end as total
from cte_vids cid join cte_vtypes cty
on cid.movementid = cty.movementid and cid.vehicleids = cty.vehicleids and cid.rown = cty.rown
答案如下:
+------------+------------+-------------+-------+
| movementid | vehichleid | vehicletype | total |
+------------+------------+-------------+-------+
| 1 | V01 | F | 200 |
| 1 | V02 | T | NULL |
| 2 | V04 | V | 140 |
| 3 | V03 | F | 300 |
| 3 | V02 | F | NULL |
+------------+------------+-------------+-------+
我使用了一个你可以创建如下的函数:
CREATE Function dbo.udf_split( @str varchar(max), @delimiter as varchar(5) )
RETURNS @retTable Table
( RowN int,
value varchar(max)
)
AS
BEGIN
DECLARE @xml as xml
SET @xml = cast(('<X>'+replace(@str,@delimiter ,'</X><X>')+'</X>') as xml)
INSERT INTO @retTable
SELECT RowN = Row_Number() over (order by (SELECT NULL)), N.value('.', 'varchar(MAX)') as value FROM @xml.nodes('X') as T(N)
RETURN
END
我根本不知道这是否可行,我什至不确定如何 google。
我正在使用 SQL Server 2014。
现在我有一个 SP,它输出 table 数据,包括 MovementID、Vehicle、VehicleType 和 Total of sales。 但它将所有车辆 id 和车辆类型组合在一起。
我需要分开车辆,我可以。 问题是总数出现重复,或一式三份等。
那么,我怎样才能 select 每个 ID(示例中的 MovementID)只出现一次该列。
当然,我会继续努力,但如果有任何想法,我们将不胜感激。
[
您可以按 MovementID 对记录进行分区,然后生成 ROW_NUMBER for each row in the partition. Then, you can use IIF 以仅在行号为 1 时显示总数,即该行是分区中的第一行。它应该看起来像这样:
SELECT MovementID, VehicleID, VehicleType, IIF(rowno = 1, Total, NULL)
FROM
(
SELECT MovementID, VehicleID, VehicleType, Total,
ROW_NUMBER() OVER (PARTITION BY MovementID ORDER BY MovementID) AS rowno
FROM <WHAT_I_HAVE_NOW>
) tmp
您可以使用 LAG
查看上一行的值。
with q as (your query here)
select
movementid, vehicleid, vecicletype,
case when movementid = lag(movementid) over (order by movementid, vehicleid)
then null else total
end as total
from q
order by movementid, vehicleid;
您可以按照以下方式拆分和加入:
;with cte_vids as (
select * from #tblmove
cross apply udf_split( vehicleids, ',')
), cte_vtypes as (
select * from #tblmove
cross apply udf_split( vehicletypes, ',')
)
select cid.movementid, cid.[value] as vehichleid, cty.[value] as vehicletype,
case when cid.rown = 1 then cid.total else null end as total
from cte_vids cid join cte_vtypes cty
on cid.movementid = cty.movementid and cid.vehicleids = cty.vehicleids and cid.rown = cty.rown
答案如下:
+------------+------------+-------------+-------+ | movementid | vehichleid | vehicletype | total | +------------+------------+-------------+-------+ | 1 | V01 | F | 200 | | 1 | V02 | T | NULL | | 2 | V04 | V | 140 | | 3 | V03 | F | 300 | | 3 | V02 | F | NULL | +------------+------------+-------------+-------+
我使用了一个你可以创建如下的函数:
CREATE Function dbo.udf_split( @str varchar(max), @delimiter as varchar(5) )
RETURNS @retTable Table
( RowN int,
value varchar(max)
)
AS
BEGIN
DECLARE @xml as xml
SET @xml = cast(('<X>'+replace(@str,@delimiter ,'</X><X>')+'</X>') as xml)
INSERT INTO @retTable
SELECT RowN = Row_Number() over (order by (SELECT NULL)), N.value('.', 'varchar(MAX)') as value FROM @xml.nodes('X') as T(N)
RETURN
END