【问题标题】:Why name column in table repeats itself?为什么表中的名称列重复?
【发布时间】:2015-03-12 21:42:33
【问题描述】:

你好,我已经处理这个查询很多天了,最后除了 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

【问题讨论】:

  • @Blam 抱歉,这是什么意思?我应该害怕什么>

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


【解决方案1】:

虽然我不建议在数据库中处理此问题,但您可以使用 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

【讨论】:

    【解决方案2】:

    在这种情况下,您可以使用带有简化条件的现有 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;
    

    【讨论】:

      猜你喜欢
      • 2016-01-19
      • 1970-01-01
      • 1970-01-01
      • 2021-02-17
      • 2021-07-05
      • 1970-01-01
      • 2015-05-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多