为什么表中的列重复自己?

时间:2015-03-12 21:42:34

标签: sql sql-server tsql stored-procedures sql-server-2012

你好我多年来一直在研究这个问题,最后几乎完成了它,除了1个问题。

它给了我这个输出

N   ConductorName   Denomination    totaltransactions   totalamount
1   NULL               NULL              1882             41610.00
1   Imran              30.00             199              5970.00
2   NULL               Imran total       199              5970.00
1   Shoaib             30.00             99               2970.00
2   NULL               Shoaib total      99               2970.00
1   Umair              10.00             792              7920.00
2   Umair              15.00             396              5940.00
3   Umair              30.00             99               2970.00
4   Umair              40.00             99               3960.00
5   Umair              60.00             198              11880.00
6   NULL               Umair total       1584             32670.00

很好但我想消除ConductorName列中的名称重复,即。

预期:

N   ConductorName   Denomination    totaltransactions   totalamount
1   NULL               NULL              1882             41610.00
1   Imran              30.00             199              5970.00
2   NULL               Imran total       199              5970.00
1   Shoaib             30.00             99               2970.00
2   NULL               Shoaib total      99               2970.00
1   Umair              10.00             792              7920.00
2   NULL               15.00             396              5940.00
3   NULL               30.00             99               2970.00
4   NULL               40.00             99               3960.00
5   NULL               60.00             198              11880.00
6   NULL               Umair total       1584             32670.00

所以每个名字都是1次,但数据完整无缺。

SP:

ALTER PROCEDURE [dbo].[ReportConductorPerformance]
@FromDate DATE,
@ToDate DATE
AS
BEGIN
    SELECT        ROW_NUMBER() OVER (PARTITION BY c.name order by c.name) 'N',CASE WHEN isnull(CAST(T .amount AS varchar(30)), c.name + ' total') LIKE '%total%' THEN NULL ELSE c.name END AS ConductorName, 
                             ISNULL(CAST(T.Amount AS varchar(30)), c.Name + ' total') AS Denomination, COUNT(*) AS totaltransactions, SUM(T.Amount) AS totalamount
    FROM            dbo.Tickets AS T INNER JOIN
                             Transport.Conductors AS c ON c.ConductorID = T.Conductor_ID
    WHERE CONVERT(DATE,ServerDateTime) BETWEEN @FromDate and @ToDate
    GROUP BY c.Name, T.Amount WITH ROLLUP 
END

2 个答案:

答案 0 :(得分:0)

虽然我不建议在数据库中处理此问题,但您可以使用case语句来获得结果,因为您已经在使用row_number

SELECT N, 
       case when N = 1 then ConductorName else NULL end ConductorName, 
       Denomination, 
       totaltransactions, 
       totalamount
FROM (
    SELECT ROW_NUMBER() OVER (PARTITION BY c.name order by c.name) 'N',
        CASE WHEN isnull(CAST(T.amount AS varchar(30)), c.name + ' total') LIKE '%total%' 
             THEN NULL
             ELSE c.name 
        END AS ConductorName, 
        ISNULL(CAST(T.Amount AS varchar(30)), c.Name + ' total') AS Denomination, 
        COUNT(*) AS totaltransactions, 
        SUM(T.Amount) AS totalamount
    FROM dbo.Tickets AS T INNER JOIN
            Transport.Conductors AS c ON c.ConductorID = T.Conductor_ID
    WHERE CONVERT(DATE,ServerDateTime) BETWEEN @FromDate and @ToDate
    GROUP BY c.Name, T.Amount WITH ROLLUP 
) T

答案 1 :(得分:0)

在这种情况下,您可以使用现有CASE语句,其中包含简化条件,仅保留分区中第一行的名称。此外,如果你遗漏了“ELSE”。默认情况下,该值为NULL,稍作简化。

另一个简单的简化是使用SQL Server的分组方法来检测您的额外行,而不是查看NULL值。

SELECT
    ROW_NUMBER() OVER (PARTITION BY c.name order by c.name) 'N',
    CASE
        WHEN T.amount IS NOT NULL AND ROW_NUMBER() OVER (PARTITION BY c.name order by c.name) = 1 THEN c.name
        END AS ConductorName,
    CASE
        WHEN grouping(T.Amount) = 0 THEN CONVERT(VARCHAR(30), T.Amount)
        ELSE c.Name + ' total'
        END AS totaltransactions,
    SUM(T.Amount) AS totalamount
FROM dbo.Tickets AS T
INNER JOIN Transport.Conductors AS c ON c.ConductorID = T.Conductor_ID
WHERE CONVERT(DATE,ServerDateTime) BETWEEN @FromDate and @ToDate
GROUP BY c.Name, T.Amount WITH ROLLUP;