SELECT Only one value per ID - SQL Server [closed]

烂漫一生 提交于 2021-02-19 07:33:39

问题


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.

[Example (Much more clear by looking at it)


回答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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!