MariaDB 查询 SUM() OVER (PARTITION BY)

MariaDB Query SUM() OVER (PARTITION BY)

我创建了一个查询,它根据特定条件(日期、isSpecial、isFirst、小时)对行进行不同的计数。 这是查询:

WITH test AS 
(
    SELECT customer_id, performance.id, performance_id, 
           Name, Date as zDate, Date, isSpecial, isFirst, hour 
    FROM recording 
    INNER JOIN performance ON performance_id = performance.id
)

SELECT id, Date, Name, isSpecial, isFirst, hour,
    IF(NOT isSpecial AND NOT isFirst AND hour,
        (SELECT SUM(CASE WHEN NOT isFirst AND NOT isSpecial
                AND hour AND Date <= zDate
              THEN 1 ELSE 0 END) 
         FROM recording 
         INNER JOIN performance ON recording.performance_id = performance.id 
         WHERE customer_id = 1
        ), 
        IF(isSpecial AND NOT isFirst AND hour,  
            (SELECT CONCAT('P',SUM(CASE WHEN NOT isFirst
                    AND isSpecial AND hour AND Date <= zDate
                  THEN 1 ELSE 0 END)) 
             FROM recording 
             INNER JOIN performance ON recording.performance_id = performance.id 
             WHERE customer_id=1
            ),  
            IF(isFirst,'First','-')
        )
    ) AS myTest 
FROM test 
WHERE customer_id = 1 
ORDER BY Date

结果:

查询为我提供了一个 customer_id 所需的结果,而我无需设置变量。

我现在已经用 SUM() OVER (PARTITION BY customer_id) 试验了很长时间,但这总是导致“子查询返回了多个记录”。

...
(SELECT CONCAT('P', SUM(CASE WHEN NOT isErst AND isProbatorik
                        AND therapiestunde AND Datum <= zDatum 
                     THEN 1 ELSE 0 END)
            OVER (PARTITION BY customer_id))
 FROM leistungserfassung 
 INNER JOIN leistung ON leistungserfassung.Leistung_id = leistung.id),
...

是否可以将此求和扩展到所有 customer_id,以便对每个 customer_id 总是再次求和?

这只是一个猜测,没有关于您的架构/表的足够详细信息:

试试这个(使用 MySQL 8.0、MariaDB 10.6、10.5、10.4 等):

注意:如果您想要 运行 SUM,只需在 window 规范中添加一个 ORDER BY Date 子句(或类似的东西)。根据您的实际要求,可以删除显式日期逻辑。没有一点数据和预期结果很难说。

The fiddle

WITH test AS (
        SELECT customer_id, performance.id, performance_id
             , Name, Date as zDate, Date, isSpecial, isFirst, hour
          FROM recording
          JOIN performance
            ON performance_id = performance.id
     )
SELECT id, Date, Name, isSpecial, isFirst, hour
     , CASE WHEN NOT isSpecial AND NOT isFirst AND hour
            THEN SUM(CASE WHEN NOT isFirst AND NOT isSpecial AND hour AND Date <= zDate THEN 1 ELSE 0 END) OVER w
            WHEN isSpecial AND NOT isFirst AND hour
            THEN CONCAT('P', SUM(CASE WHEN NOT isFirst AND isSpecial AND hour AND Date <= zDate THEN 1 ELSE 0 END) OVER w)
            WHEN isFirst
            THEN 'First'
            ELSE '-'
        END AS myTest
  FROM test
WINDOW w AS (PARTITION BY customer_id)
 ORDER BY customer_id, Date
;

向 window 函数添加 运行 SUM(通过 Date)行为并删除显式 Date <= zDate 逻辑:

WITH test AS (
        SELECT customer_id, performance.id, performance_id
             , Name, Date, isSpecial, isFirst, hour
          FROM recording
          JOIN performance
            ON performance_id = performance.id
     )
SELECT id, Date, Name, isSpecial, isFirst, hour
     , CASE WHEN NOT isSpecial AND NOT isFirst AND hour
            THEN SUM(CASE WHEN NOT isFirst AND NOT isSpecial AND hour THEN 1 ELSE 0 END) OVER w
            WHEN isSpecial AND NOT isFirst AND hour
            THEN CONCAT('P', SUM(CASE WHEN NOT isFirst AND isSpecial AND hour THEN 1 ELSE 0 END) OVER w)
            WHEN isFirst
            THEN 'First'
            ELSE '-'
        END AS myTest
  FROM test
WINDOW w AS (PARTITION BY customer_id ORDER BY Date)
 ORDER BY customer_id, Date
;

结果(无数据):

id Date Name isSpecial isFirst hour myTest

设置(我确定这些表不正确。问题没有包括这个细节):

CREATE TABLE recording   ( id int, performance_id int, customer_id int );

CREATE TABLE performance (
   id int, Name VARCHAR(20), Date date
 , isSpecial int, isFirst int, hour int
);