SQL - Create a match matrix

1

Good afternoon, This question would be the next step to the question asked in " Doubt in complex grouping sql " and that a solution was already obtained.

I summarize it and indicate the new question.

I have a table with tickets like this, without a ticket identifier field as such, but the date + id Client could be taken as an identifier. The same ticket appears in the same color:

The initial task was to know for each item, the sum of times others have been purchased on the same ticket.

Thanks to the user Marcos Crispino I found the sql that I wanted to do:

select A.articulo_id, A.articulo_desc, count(*) as total
from tickets_prueba A
where exists (select *
          from tickets_prueba B
          where B.articulo_id = 1
            and A.fecha_ticket_id = B.fecha_ticket_id
            and A.cliente_id = B.cliente_id)
and A.articulo_id <> 1
group by A.articulo_id

This brings out, for the article "Candy Strawberry" The following table:

That is to say, when the Strawberry Caramel has been bought, the banana ones have also been bought twice, and twice the coconut ones.

Well, now I would need to extend this for all articles, through a product matrix, in which, in each cell, the sum of times a product Y of a column has been bought together with a product X appears of a row, or vice versa. I should get something like this:

           Articulo_1   Articulo_2  Articulo_3
Articulo_1     0           2            2
Articulo_2     2           0            1
Articulo_3     2           1            0

The actual table on which I want to make the query has 85 different products, and if I try to do it with 85 queries united with UNION, it stays in an infinite loop, I would need to do something more optimized. Besides, this does not take it out in "Matrix" format but in a list as the second image, and then it would have to be transposed in excel.

Any ideas? Thank you very much.

P.D. I add some things that I have done:

CREATE TABLE prueba as
select * from (
(select (select distinct articulo_id from tickets_yogures b where articulo_id=178342) as articulo_principal, a.articulo_id, a.articulo_desc, (round(count(*)/8)) from tickets_yogures a, tickets_yogures b where exists (select *  from tickets_yogures b  where b.articulo_id = 178342 and a.fecha_ticket_id = b.fecha_ticket_id  and a.cliente_id = b.cliente_id)  and a.articulo_id <>178342 group by a.articulo_id) union 
(select (select distinct articulo_id from tickets_yogures b where articulo_id=165506) as articulo_principal, a.articulo_id, a.articulo_desc, (round(count(*)/8)) from tickets_yogures a, tickets_yogures b where exists (select *  from tickets_yogures b  where b.articulo_id = 165506 and a.fecha_ticket_id = b.fecha_ticket_id  and a.cliente_id = b.cliente_id)  and a.articulo_id <>165506 group by a.articulo_id) union ....

But as I was saying, for the 85 products that have to be checked, the query becomes very heavy.

I have also tried the following, to make a list of items purchased on each ticket (there are 85 columns, one for each product created with GROUP_CONCAT) and 0 or 1 in each cell depending on whether that ticket (row) has been bought that item:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
  CONCAT(
  'SUM(CASE WHEN articulo_id = "',
  articulo_id,'" THEN ',1,' ELSE 0 end) AS articuloid_',
  articulo_id)
)
INTO @sql
FROM tickets_prueba;

SET @sql = CONCAT('CREATE TABLE tickets_matriz AS SELECT FECHA_TICKET_ID, cliente_id,', @sql,
              ' FROM tickets_prueba GROUP BY fecha_ticket_id, cliente_id');
PREPARE stmt FROM @sql;
EXECUTE stmt;
deallocate prepare stmt;

But now I would miss the second step that is to make the matrix in which each cell is the sum of the match of article X with the Y.

    
asked by Psichodelik 10.04.2017 в 16:16
source

0 answers