【问题标题】:Use DISTINCT with ORDER BY clause将 DISTINCT 与 ORDER BY 子句一起使用
【发布时间】:2015-07-09 16:37:12
【问题描述】:

我想改变我的以下存储过程

ALTER Procedure [dbo].[spEGCRedemptionReportForMHR]  

@DateTo datetime,
@DateFrom datetime,
@MerchantID varchar(11),
@Pan varchar(16)
As
Set @DateTo = @DateTo +1
Select Distinct
Convert(varchar(50),pt.TransactionDate,103) 'TransactionDate',
m.MerchantName1 MerchantName,
m.MerchantAddress Location,
m.MerchantID,
pt.TerminalID,
pt.batchnumber 'Batch #',
pt.SequenceNumber 'Receipt #',
pt.PAN 'Card Number',
c.EmbossName 'Card Holder Name',

Convert(Decimal(10,2),Case when pt.TransactionTypeID=2 then (pt.TotalAmount) end) As 'Points Redeemed',
Convert(Decimal(10,2),Case when pt.TransactionTypeID=2 then (((pt.TotalAmount)/(cc.usdconversionrate))/2) end) as 'Total Payment Amount (AED)', --/cc.USDConversionRate end) As 'Total Amount in AED',
Convert(Decimal(10,2),Case when pt.TransactionTypeID=2 then (((pt.TotalAmount)/(cc.usdconversionrate))/2) -15 end) as 'Total loaded Amount (AED)',
3.00 as 'Procco Share',
Convert(Decimal(10,2),Case when pt.TransactionTypeID=2 then (((pt.TotalAmount)/(cc.usdconversionrate))/2) - 3 end) as 'Settlement Amount'

from POS_Transactions pt
inner join Terminal t on t.TerminalID=pt.TerminalID
inner join Merchant m on m.MerchantID=t.MerchantID
inner join Card c on c.EmbossLine=pt.PAN
inner join Share s on s.MerchantID=m.MerchantID,Currency cc
where IsEmaar =1 and
cc.CurrencyCode='AED'
--and m.isemaarmerchant = 1
and (m.MerchantID=@MerchantID or @MerchantID='-999')
and (pt.TransactionDate>=@datefrom and pt.TransactionDate<=@dateto)
and (pt.PAN=@Pan or @Pan ='-999')
order by pt.TransactionDate

但每次我尝试执行它都会引发错误

ORDER BY items must appear in the select list if SELECT DISTINCT is specified.

我已经在我的选择中使用了pt.TransactionDate,但它仍然要求我包含它,因为它在我的 order by 子句中。我的查询可能有什么问题?

【问题讨论】:

  • 您应该在选择中直接使用order by Convert(varchar(50),pt.TransactionDate,103)pt.TransactionDate

标签: sql-server select sql-order-by distinct


【解决方案1】:

试试:

ORDER BY 'TransactionDate'

【讨论】:

    【解决方案2】:

    这个错误没有多大帮助,但ughai 的评论是正确的。引擎特别关注如何在 SELECT 语句中修改列,并且确切的形式必须包含在“ORDER BY”中。

    我在出于输出原因连接列时遇到了这个问题,而且很快就变得丑陋了。

    你必须

    ORDER BY Convert(varchar(50),pt.TransactionDate,103)
    

    【讨论】:

      【解决方案3】:

      如果您使用 GROUP BY 而不是 DISTINCT 来消除重复项,那么您可以包括分组字段,无论它们是否在选择列表中。缺点是您必须列出 所有 使用的列,但这可以做到。

      GROUP BY 
      pt.TransactionDate,
      m.MerchantName1,
      m.MerchantAddress ,
      m.MerchantID,
      pt.TerminalID,
      pt.batchnumber,
      pt.SequenceNumber,
      pt.PAN ,
      c.EmbossName,
      pt.TransactionTypeID,
      pt.TotalAmount,
      cc.usdconversionrate
      ORDER BY pt.TransactionDate
      

      【讨论】:

        【解决方案4】:

        是的,列 pt.TransactionDate 出现在 SELECT 中,但在 CONVERT 函数内部如下:

        CONVERT(VARCHAR(50), pt.TransactionDate, 103) 'TransactionDate',
        

        单独添加 pt.TransactionDate 作为额外的列,如下所示:

          ...     
          SELECT DISTINCT
            CONVERT(VARCHAR(50), pt.TransactionDate, 103) 'TransactionDate',
            pt.TransactionDate, -- <-- here
            m.MerchantName1 MerchantName,
            m.MerchantAddress Location,
            m.MerchantID,
            pt.TerminalID,
          ....
        

        【讨论】:

        • 为什么我要显示同一个字段两次?没有其他选择吗?
        • 为什么不呢。这应该没什么大不了的。如果您真的不希望它出现在选择列表中,那么您必须按照上面的建议按 CONVERT(VARCHAR(50), pt.TransactionDate, 103) 排序。但请注意,它可能不会按照您想要的方式排序。
        猜你喜欢
        • 2017-09-24
        • 1970-01-01
        • 1970-01-01
        • 2011-01-28
        • 1970-01-01
        • 1970-01-01
        • 2020-06-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多