С предложением Cube, генерирующим повторяющиеся строки

Предложение «с кубом» генерирует повторяющиеся строки, и я не понимаю, почему. Вот пример:

CREATE TABLE venta_mes_hist (
    tienda_id INT,
    empresa_id INT,
    dia_id DATE,
    total_linea_brut DECIMAL(18, 2)
);

CREATE TABLE lk_tienda (
    tienda_id INT,
    empresa_id INT,
    tienda_desc VARCHAR(50)
);


-- Insert data into lk_tienda
INSERT INTO lk_tienda (tienda_id, empresa_id, tienda_desc)
VALUES 
(1, 1, 'SHIBORI'),
(2, 1, 'NARA'),
(3, 1, 'OSAKA');

-- Insert data into venta_mes_hist
INSERT INTO venta_mes_hist (tienda_id, empresa_id, dia_id, total_linea_brut)
VALUES
(1, 1, '2023-03-01', 100.00),
(1, 1, '2023-03-28', 2544.84),
(1, 1, '2023-04-15', 200.00),
(2, 1, '2023-03-01', 150.00),
(2, 1, '2023-03-28', 3000.00),
(2, 1, '2023-04-15', 250.00),
(3, 1, '2023-03-01', 200.00),
(3, 1, '2023-03-28', 3200.00),
(3, 1, '2023-04-15', 300.00),
(1, 1, '2023-05-10', 500.00);

Затем я запускаю этот запрос:

DROP TABLE IF EXISTS #avenut;
SET DATEFORMAT mdy;

select cast(lk_tienda.tienda_desc as varchar(35)) Botiga,venta_mes_hist.dia_id Dia,cast(month(venta_mes_hist.dia_id) as int) Mes,
 sum(venta_mes_hist.total_linea_brut) Venut_valor_brut
 into #avenut
 from  lk_tienda, venta_mes_hist
 where 
 lk_tienda.tienda_id = venta_mes_hist.tienda_id and lk_tienda.empresa_id = venta_mes_hist.empresa_id 
 and venta_mes_hist.empresa_id in ('1') 
 and venta_mes_hist.dia_id >= '03/01/2023'
 and venta_mes_hist.dia_id <= '06/06/2024'
 group by cast(lk_tienda.tienda_desc as varchar(35)), venta_mes_hist.dia_id, cast(month(venta_mes_hist.dia_id) as int)
 with cube 
 order by cast(lk_tienda.tienda_desc as varchar(35)), venta_mes_hist.dia_id, cast(month(venta_mes_hist.dia_id) as int)

Когда я бегу:

SELECT * FROM #avenut
WHERE Botiga = 'SHIBORI' AND Dia = '2023-03-28';

Он возвращает две строки:

Botiga  Dia Mes Venut_valor_brut
SHIBORI 2023-03-28  3   2544.84
SHIBORI 2023-03-28  3   2544.84

Как это возможно? Я, конечно, ожидаю одну строку, как будто я правильно понимаю, предложение With CUBE генерирует итоги, вставляя в некоторые поля строки с нулевыми значениями.

Если вы удалите столбец месяца, он вернет одну строку. А если вы добавите столбец «Новый год», сохранив столбец «Месяц», он вернет 4 строки!

От вредных привычек: использование старых JOINов Сейчас 2024 год; у вас было 32 года, чтобы принять синтаксис ANSI-92 JOIN.
Thom A 06.06.2024 11:13
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
1
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваша проблема в том, что вы добавили cast(month(venta_mes_hist.dia_id as int)) в качестве одного из пунктов group by. Во-первых, в этом не было необходимости, поскольку вы также добавили venta_mes_hist.dia_id в качестве предложения (так что вы просто можете выполнять расчет только в select), и это также портит cube, который будет умножать все предложения. Итак, это эквивалент в grouping sets:

 group by grouping sets (
   (cast(lk_tienda.tienda_desc as varchar(35)), venta_mes_hist.dia_id, cast(month(venta_mes_hist.dia_id) as int)),
   (cast(lk_tienda.tienda_desc as varchar(35)), venta_mes_hist.dia_id),
   (cast(lk_tienda.tienda_desc as varchar(35)), cast(month(venta_mes_hist.dia_id) as int)),
   (venta_mes_hist.dia_id, cast(month(venta_mes_hist.dia_id) as int)),
   (cast(lk_tienda.tienda_desc as varchar(35))),
   (venta_mes_hist.dia_id),
   (cast(month(venta_mes_hist.dia_id) as int)),
   ()
 )

Просто удалите этот пункт из group by. Его также можно удалить из order by, поскольку он функционально зависит от

  • Обратите внимание, что with cube устарел, вместо него используйте cube().
  • cast(... as varchar(35)) кажется ненужным, вы можете удалить его.
select
  lk_tienda.tienda_desc Botiga,
  venta_mes_hist.dia_id Dia,
  cast(month(venta_mes_hist.dia_id) as int) Mes,
  sum(venta_mes_hist.total_linea_brut) Venut_valor_brut
 from  lk_tienda, venta_mes_hist
 where 
 lk_tienda.tienda_id = venta_mes_hist.tienda_id and lk_tienda.empresa_id = venta_mes_hist.empresa_id 
 and venta_mes_hist.empresa_id in ('1') 
 and venta_mes_hist.dia_id >= '03/01/2023'
 and venta_mes_hist.dia_id <= '06/06/2024'
 group by cube (
   lk_tienda.tienda_desc,
   venta_mes_hist.dia_id
 )
 order by
   lk_tienda.tienda_desc,
   venta_mes_hist.dia_id;

Вы также можете сделать это, используя grouping sets, что некоторым кажется более понятным.

 group by grouping sets (
   (lk_tienda.tienda_desc, venta_mes_hist.dia_id),
   (lk_tienda.tienda_desc),
   (venta_mes_hist.dia_id),
   ()
 )

db<>рабочий пример

Другие вопросы по теме