对于查询中的每个分区,做一个案例 select

For each partition in query, do a case select

来自 CTE 的以下查询结果:

+---------+----------+----------+----------+---------------------+
|  STORE  |   DATE   |   TIME   | RESPONSE | ROW_NUMBER_BY_STORE |
+---------+----------+----------+----------+---------------------+
| Store 1 | 11/15/19 | 15:37:40 |     1    |          1          |
+---------+----------+----------+----------+---------------------+
| Store 1 | 11/15/19 | 15:37:40 |     1    |          2          |
+---------+----------+----------+----------+---------------------+
| Store 1 | 11/15/19 | 16:55:12 |     2    |          3          |
+---------+----------+----------+----------+---------------------+
| Store 1 | 11/15/19 | 16:55:12 |     2    |          4          |
+---------+----------+----------+----------+---------------------+

我一直在尝试找出是否有任何方法可以在我的单个商店的查询结果中显示:

当然,我的 table 上有大量商店,我知道这可以通过 case 语句实现,但此查询中的 table 最初并未分区,并且我尝试添加一个 row_number() 函数并按 "store" 列进行分区,并将我的查询包装在 CTE 中以便能够查询行号函数,但似乎我只是不带着它去任何地方。所以我想知道是否有任何其他方法可以 运行 在每个行组上进行这样的查询。

编辑:

这是我的 CTE 的简化版本。不发布原件,因为它是一个包含大量连接的大型查询:

WITH CTE AS
(
SELECT
        STORE_ID,
        STORE,
        CONVERT (varchar, INPUT_DATE, 103) AS DATE,
        TIME, 
        RESPONSE,
        ROW_NUMBER() OVER (PARTITION BY STORE ORDER BY STORE) AS STORE


FROM TABLE_1

WHERE   INPUT_DATE BETWEEN 2019-11-15 AND 2019-11-15

)

SELECT *

FROM CTE

下面使用OUTER APPLY()

怎么样
DECLARE @Tab TABLE (STORE INT,DT DATE, TIME time(3), RESPONSE INT, ROW_NUMBER_BY_STORE INT)


INSERT INTO @Tab
VALUES 
(1,'11/15/19','15:37:40',1,1),
(1,'11/15/19','15:37:40',1,2),
(1,'11/15/19','16:55:12',2,3),
(1,'11/15/19','16:55:12',2,4),
(2,'11/15/19','16:55:12',2,1),
(2,'11/15/19','16:55:12',2,2),
(3,'11/15/19','16:55:12',1,1),
(3,'11/15/19','16:55:12',1,2)


SELECT t.Store
     , t.Dt
     , t.Time
     , CASE WHEN tt.DistinctResponse = 3 THEN 1
            WHEN tt.DistinctResponse = 2 THEN 2
            ELSE NULL END AS Response
     , t.Row_Number_By_Store
FROM @Tab t
OUTER APPLY(
            SELECT t2.Store, SUM(DISTINCT t2.Response) AS DistinctResponse
            FROM @Tab t2
            WHERE t2.Store = t.Store
            GROUP BY t2.Store
           ) tt

这是一个同样从 CTE 开始的方法。

它使用 window 版本的 MIN 和 MAX。
还有一个用模数计算标志的技巧。

WITH CTE_DATA AS
(
  SELECT 
    STORE
  , CAST(dt AS DATE) AS [DATE]
  , CAST(dt AS TIME) AS [TIME] 
  , RESPONSE
  , ROW_NUMBER_BY_STORE
  FROM (VALUES
  ('Store1','2019-11-15 15:37:40',1,1),
  ('Store1','2019-11-15 15:37:40',1,2),
  ('Store1','2019-11-15 16:55:12',2,3),
  ('Store1','2019-11-15 15:37:12',2,4),
  ('Store2','2019-11-16 15:37:40',1,1),
  ('Store2','2019-11-16 15:37:40',1,2),
  ('Store3','2019-11-17 16:55:12',2,3),
  ('Store3','2019-11-17 15:37:12',2,4)
  ) v(STORE, dt, RESPONSE, ROW_NUMBER_BY_STORE)
)
, CTE_DATA2 AS
(
  SELECT *
  , CAST(IIF((
      RESPONSE
    + MIN(RESPONSE) 
      OVER (PARTITION BY STORE, [DATE]) 
    + MAX(RESPONSE) 
      OVER (PARTITION BY STORE, [DATE]))%2 = 1, 0, 1
    ) AS BIT) AS Flag
  FROM CTE_DATA
)
SELECT STORE, [DATE], [TIME], RESPONSE, ROW_NUMBER_BY_STORE
FROM CTE_DATA2
WHERE Flag = 1
ORDER BY STORE, [DATE], ROW_NUMBER_BY_STORE;
GO
STORE  | DATE                | TIME     | RESPONSE | ROW_NUMBER_BY_STORE
:----- | :------------------ | :------- | -------: | ------------------:
Store1 | 15/11/2019 00:00:00 | 15:37:40 |        1 |                   1
Store1 | 15/11/2019 00:00:00 | 15:37:40 |        1 |                   2
Store3 | 17/11/2019 00:00:00 | 16:55:12 |        2 |                   3
Store3 | 17/11/2019 00:00:00 | 15:37:12 |        2 |                   4

db<>fiddle here

我建议使用 window 函数,但像这样:

select cte.*
from (select cte.*,
             sum(case when response = 1 then 1 else 0 end) over (partition by store) as response_1,
             sum(case when response = 2 then 1 else 0 end) over (partition by store) as response_2
      from cte 
      where response in (1, 2)
     ) cte
where response_2 > 0 and
      (response_1 > 0 and response = 1 or
       response_1 = 0 and response = 2
      );