问题
I dont know is this is possible at all, I´m not even sure how to google it.
Im using SQL Server 2014.
Right now I have a SP that outputs a table with data including MovementID, Vehicle, VehicleType and Total of sales. But it groups all the vehicles ids and vehicles types with a total.
I need to separate vehicles, which I can. The problem is that the totals appear duplicated, or triplicated etc.
So, how can I only select that column only one time per ID (MovementID in the example).
I'll keep trying, of course, but any idea would be appreciated.
[
回答1:
You can use LAG
to see values of the previous row.
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;
回答2:
You can PARTITION the records by MovementID and then generate a ROW_NUMBER for each row in the partition. Then, you can use IIF to only display the total if the row number is 1, i.e. the row is the first row in the partition. It should look something like this:
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
回答3:
You can split and join as below:
;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
Answers as below:
+------------+------------+-------------+-------+ | movementid | vehichleid | vehicletype | total | +------------+------------+-------------+-------+ | 1 | V01 | F | 200 | | 1 | V02 | T | NULL | | 2 | V04 | V | 140 | | 3 | V03 | F | 300 | | 3 | V02 | F | NULL | +------------+------------+-------------+-------+
I used a function which you can create as below:
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
来源:https://stackoverflow.com/questions/58105133/select-only-one-value-per-id-sql-server