Как показать строки в пачках из трех из двух таблиц в MySQL - PullRequest
1 голос
/ 01 октября 2019

Это дополнительный вопрос к Как показать строки в пачках по три в MySQL

У меня есть две таблицы:

mytable

ID  Type  Timestamp
1   A     101   
2   A     102
3   B     103
4   B     104   
5   A     105   
6   B     106   
7   A     107
8   A     108
9   B     109   
10  A     110   
11  B     111
12  B     112


mytable 2

ID2  Text  Status
1    x     1   
2    x     1
3    y     1
4    y     1   
5    x     1   
6    y     1   
7    x     1
8    x     1
9    y     1   
10   x     0   
11   y     1
12   y     0

Я хочупоказать результат, отсортированный по типу и метке времени, где каждые 3 строки тип изменяется следующим образом (пропускаются строки с Status = 0):

ID  Type  Timestamp  Text
1   A     101        x
2   A     102        x
5   A     105        x
3   B     103        y
4   B     104        y
6   B     106        y
7   A     107        x
8   A     108        x
9   B     109        y
11  B     111        y

Я пробовал это:

SELECT id, type, timestamp, text  
FROM (
SELECT 
    t.*,t2.text,t2.id2, 
    @rn := CASE WHEN @type = type THEN @rn + 1 ELSE 1 END rn,
    @type := type
FROM 
    mytable t, mytable2 t2
    WHERE t2.id2=t.id
    AND status=1
    CROSS JOIN (SELECT @type := NULL, @rn := 1) x
ORDER BY type, timestamp
) x

ORDER BY 
FLOOR((rn - 1)/3),
type, 
timestamp;

[Демонстрация по БД Fiddle] (https://www.db -fiddle.com / f / 7urWNPqXyGQ5ANVqxkjD7q / 1 )

1 Ответ

1 голос
/ 01 октября 2019

Для начала вам просто нужно исправить JOIN, синтаксис которого неверен (как правило, предложение WHERE идет после всех JOIN s, и мы предпочитаем явные объединения неявным объединениям).

Также, как прокомментировал Мадхур Бхайя, использование фильтров с увеличенными переменными является сложным. Чтобы это работало должным образом, нам нужно объединить две таблицы в подзапросе и выполнить упорядочение внутри самого подзапроса, а затем перейти к логике переменных.

Рассмотрим:

SELECT id, type, timestamp, text  
FROM (
SELECT 
    t.*,
    @rn := CASE WHEN @type = type THEN @rn + 1 ELSE 1 END rn,
    @type := type
FROM 
    (
        SELECT t.*, t2.text,t2.id2
        FROM mytable t
        INNER JOIN mytable2 t2 ON t2.id2=t.id AND status=1
        ORDER BY type, timestamp
    ) t
    CROSS JOIN (SELECT @type := NULL, @rn := 1) x
) x
ORDER BY FLOOR((rn - 1)/3), type, timestamp;

Демонстрация на DB Fiddle :

| id  | type | timestamp | text |
| --- | ---- | --------- | ---- |
| 1   | A    | 101       | x    |
| 2   | A    | 102       | x    |
| 5   | A    | 105       | x    |
| 3   | B    | 103       | y    |
| 4   | B    | 104       | y    |
| 6   | B    | 106       | y    |
| 7   | A    | 107       | x    |
| 8   | A    | 108       | x    |
| 9   | B    | 109       | y    |
| 11  | B    | 111       | y    |
...