T-Sql

在查詢期間更改值後組合以前不同的行

  • March 7, 2020

我目前正在執行一個查詢,該查詢應該返回按單個客戶分組的銷售人員的總收入。

由於處理使用者輸入的方式,有很多近乎重複的行,客戶端名稱有輕微的拼寫錯誤/添加。正如您在下面的程式碼中看到的那樣,我正在嘗試刪除其中一個問題字元串,以防止相同客戶端的重複行。

但是,儘管 CASE 語句成功刪除了“@iraPrefix”,但具有現在相同客戶名稱的行仍然沒有組合在一起,因為它們的收入欄位沒有被求和。

我應該如何處理這個?

DECLARE @iraPrefix VARCHAR(7)
DECLARE @iraLen INT
SET @iraPrefix = 'FOO BAR '
SET @iraLen = LEN(@iraPrefix)

SELECT [client] = (
          CASE SUBSTRING([name], 1, @iraLen)
              WHEN @iraPrefix THEN SUBSTRING([name], @iraLen+2, (LEN([name]) - @iraLen))
              ELSE [name]
          END
      )
      , CONCAT( sal.firstname
              , ' '
              , sal.lastname) AS [salesman]
      , [revenue] = SUM(net)

以下是不刪除前綴的查詢結果範例:

在此處輸入圖像描述

目前查詢結果範例:

在此處輸入圖像描述

我想要的結果的一個例子:

在此處輸入圖像描述

再聚合一次。

你可以這樣做

  • 實現中間結果集 ( SELECT ... INTO #intermediate FROM...),然後聚合記憶體的中間結果
  • 將您目前的查詢包裝在一組括號中,並SELECT針對您分配給它的任何別名進行 ing。

有關範例,請參見此小提琴。但是為了冗長,假設您的數據都儲存在一個名為 的表中barfoo,那麼您可以使用通用表表達式(或 CTE)執行此操作的一種方法是……

DECLARE @iraPrefix VARCHAR(7);
DECLARE @iraLen INT;
SET @iraPrefix = 'FOO BAR ';
SET @iraLen = LEN(@iraPrefix);

WITH L1 AS (
  SELECT [client] = (
          CASE SUBSTRING([name], 1, @iraLen)
              WHEN @iraPrefix THEN SUBSTRING([name], @iraLen+2, (LEN([name]) - @iraLen))
              ELSE [name]
          END
      )
      , CONCAT( sal.firstname
              , ' '
              , sal.lastname) AS [salesman]
      , [revenue] = SUM(net)
  FROM barfoo as sal
  GROUP BY [name],CONCAT( sal.firstname
                     , ' '
                     , sal.lastname) 
)
SELECT 
       [client],
       [salesman],
       SUM([revenue]) AS [revenue]
FROM L1
GROUP BY [client],
       [salesman];

我喜歡使用 CTE 將清理和聚合步驟分開。這使得每一個都易於理解、更改和調試。就像是

; with Clean as
(

   SELECT [client] = (
              CASE SUBSTRING([name], 1, @iraLen)
                  WHEN @iraPrefix THEN SUBSTRING([name], @iraLen+2, (LEN([name]) - @iraLen))
                  ELSE [name]
              END
          )
          , CONCAT( sal.firstname
                  , ' '
                  , sal.lastname) AS [salesman]
          , net
)
select
   client
  ,salesman
  ,[revenue] = SUM(net)
from Clean
group by client, salesman;

不能保證在執行時首先執行 CTE,然後執行聚合。優化器可能會重新排列這些位,但會選擇最佳性能。不過,它提供的內容可以保證實現您提供的查詢。這讓我們開發人員可以根據我們選擇的最佳人類理解來安排查詢,在這種情況下使用 CTE。(在某些特殊情況下,優化器給出的計劃效果不佳,最好的解決方案是重新安排 SQL;這不會是其中一種情況。)

引用自:https://dba.stackexchange.com/questions/261384