Turn specific rows into columns

Asked

Viewed 47 times

0

I have a table of activity histories and would like to turn some rows (of some specific status) into columns:

Current Table:

inserir a descrição da imagem aqui

The statuses I wish to turn into columns are these:

mod_analise_status_id = 10 (FORMALIZADO)

mod_analise_status_id = 9 OR mod_analise_status_id = 12 (CONFERIDO)

That is, create a column FORMALIZED and another column CONFERRED where the column value will be displayed datetime. I’d stay that way down:

Desired table:

inserir a descrição da imagem aqui

In my example the CHECKED column did not return the right values. My SQL code is this:

SELECT
h.solicitation_id as 'SOLICITATION',
case 
    when (h.mod_analise_status_id = 10)   then h.datetime
    else h.datetime
end
as 'FORMALIZADO',
case 
    when (h2.mod_analise_status_id =9 AND h2.mod_analise_status_id =12) then h2.datetime
    else h2.datetime
end
as 'CONFERIDO'
FROM
    `negocios`.`mod_analise_historic` h
    INNER JOIN `negocios`.`mod_analise_historic` h2
    ON h.solicitation_id = h2.solicitation_id AND MONTH (h.datetime) = 06
WHERE
    MONTH (h.datetime) = 06
    AND YEAR (h.datetime) = 2021

Table: http://sqlfiddle.com/#! 9/8f4f3b

  • (h2.mod_analise_status_id =9 AND h2.mod_analise_status_id =12) this will never return, it is not possible for the value to be at the same time (AND) equal to 9 and 12 :) should use a OR ai

  • Yes, true. It was an error when doing several tests. But in fact the problem persists even when fixing it.

  • 2

    without having an example with data that can be analyzed, it is difficult to help more than that. Try to mount an example, it can be in sqlfiddle or db-fiddle to facilitate understanding

  • From what I understand, you only want as a result the records that have already been "Formalized" and "Checked", correct? For example, if a request has been Formalized but has not been "Checked", you do not want that request. It would be good for you to create the example in sqlfiddle as @Ricardopunctual suggested.

  • @Ricardopunctual I created the example with part of my database

  • @Clarckmaciel, to be exact. I need to return the rows that have both status, as each one a column, so that I can calculate the time spent between one and the other, and try to display in another column.

  • In your Fiddle example you do not show mod_analise_status_id equal to 9, 10 or 12. You can edit it to look like your situation?

  • Testing: SELECT
h.solicitation_id as 'SOLICITATION',
case
 when (h.mod_analise_status_id = 10) then h.datetime
 else h.datetime
end
as 'FORMALIZADO',
case
 when (h2.mod_analise_status_id =9 or h2.mod_analise_status_id =12) then h2.datetime
 else h2.datetime
end
as 'CONFERIDO'
FROM
 mod_analise_historic h
 INNER JOIN mod_analise_historic h2
 ON h.solicitation_id = h2.solicitation_id
 and h2.mod_analise_status_id =9 or h2.mod_analise_status_id =12
WHERE
 MONTH (h.datetime)= 06
 AND YEAR (h.datetime)= 2021
 AND H.mod_analise_status_id= 10

  • This answers your question? PIVOT - SELECT reversing row and column

  • @Clarckmaciel, in this sql did not give, it repeats the same request ID and the CHECKED and FORMALIZED columns do not beat the months and years.

  • @Sorack is the same logic that I am using in my query, however the context of datetime and business rule are different, I can not get the desired result.

  • @gugoan, repetition occurs because it is a history table where there can be repetition of an identifier. You need to include logic to inform which record you want from the second table. So, I believe you want to: Solicitação; FORMALIZADO; CONFERIDO;. But the conferido considers as true both 9 and 12, and as you are interested in the time difference, it would be interesting the shorter date given for that request(9 or 12) in that year, correct?

  • with the data you entered in the example is not possible to simulate your problem, I changed some status and dates to match with your query, see if this is what you want: http://sqlfiddle.com/#! 9/6ce917/1 if it is not, edit the data to show the problem. In the request line "24" appear the two dates, this seems to be wrong because of the join, but see the query and confirm

  • @Clarckmaciel, yes, that even the repetition will occur, has several histories for the same request. I need exactly from the request that has a history of FORMALIZED and tbm has a history of CONFERRED, so I can calculate the time between them and measure productivity.

  • @Ricardopunctual, in this query did not work, Testi here and some histories of a request for example did not come. I almost thought it would work, it would just remove the nulls. I will

  • That’s what I figured, the problem is Join :)

  • @gugoan, I created a simplified structure to test your situation, make sure I understand what you need at http://sqlfiddle.com/#! 9/224d5b/4 .

Show 12 more comments

1 answer

0


In the situation where you have a history table, basically, we will have a table with 3 fields: ID, Datarecord, Observation; These fields will answer the questions: With which record happened? When? What? Who?.
The field ID: related to another table, in this example, we will consider the solicitation_id which must be related to a business table, probably called solicitation.
The field DataHoraRegistro: Informs when an event has occurred, we will admit the field called datetime in his case.
The field Observação, status_id, important_information: It will contain relevant information from that record.
Note an example of the relationship between tables that contains a history table:
Tabela com histórico

Example available in: SQL Fiddle

Mysql 5.6 Schema Setup:

create table mod_analise_historic
(
    id bigint unsigned auto_increment,
    solicitation_id int null,
    datetime datetime null,
    mod_analise_status_id int null,
    constraint id
        unique (id)
);

insert into mod_analise_historic (id, solicitation_id, datetime, mod_analise_status_id) values (1, 25279, '2021-06-01 12:00:00', 10);
insert into mod_analise_historic (id, solicitation_id, datetime, mod_analise_status_id) values (2, 25246, '2021-06-01 06:46:59', 10);
insert into mod_analise_historic (id, solicitation_id, datetime, mod_analise_status_id) values (3, 24842, '2021-06-01 14:00:00', 10);
insert into mod_analise_historic (id, solicitation_id, datetime, mod_analise_status_id) values (4, 25246, '2021-06-01 08:47:46', 9);
insert into mod_analise_historic (id, solicitation_id, datetime, mod_analise_status_id) values (5, 25246, '2021-05-20 07:00:00', 1);
insert into mod_analise_historic (id, solicitation_id, datetime, mod_analise_status_id) values (6, 25246, '2021-06-01 08:30:00', 12);

Consultation 1:

Select * from mod_analise_historic

Upshot:

id solicitation_id datetime mod_parse_status_id
1 25279 2021-06-01T12:00:00Z 10
2 25246 2021-06-01T06:46:59Z 10
3 24842 2021-06-01T14:00:00Z 10
4 25246 2021-06-01T08:47:46Z 9
5 25246 2021-05-20T07:00:00Z 1
6 25246 2021-06-01T08:30:00Z 12

Query 2 - Displaying 'Formalized' and shorter date for 'Conferred':

SELECT
h.solicitation_id as 'SOLICITATION',
case
    when (h.mod_analise_status_id = 10)   then h.datetime
end
as 'FORMALIZADO',
case
    when (h2.mod_analise_status_id =9 or h2.mod_analise_status_id =12) then h2.datetime
end
as 'CONFERIDO'
FROM
    `mod_analise_historic` h
    INNER JOIN `mod_analise_historic` h2
            ON h.solicitation_id = h2.solicitation_id
           and (h2.mod_analise_status_id =9 or h2.mod_analise_status_id =12)
           and h2.datetime = (Select min(datetime)
                                from mod_analise_historic h3
                               where h3.solicitation_id = h2.solicitation_id
                                 and YEAR(h3.datetime) = YEAR(h2.datetime)
                                 and (h3.mod_analise_status_id =9 or h3.mod_analise_status_id =12)
               )
WHERE
    MONTH (h.datetime) = 06
    AND YEAR (h.datetime) = 2021
    AND H.mod_analise_status_id = 10

Results:

SOLICITATION FORMALIZED CONFERRED
25246 2021-06-01T06:46:59Z 2021-06-01T08:30:00Z

Query 3: Set of records that are 'FORMALIZED' status'

SELECT h.solicitation_id as 'SOLICITATION',
case
    when (h.mod_analise_status_id = 10)   then h.datetime
end
as 'FORMALIZADO'
FROM
    `mod_analise_historic` h
WHERE
    MONTH(h.datetime) = 06
    AND YEAR (h.datetime) = 2021

Results:

SOLICITATION FORMALIZED
25279 2021-06-01T12:00:00Z
25246 2021-06-01T06:46:59Z
24842 2021-06-01T14:00:00Z
25246 (null)
25246 (null)

Query 4: 'Conferred' with date null when the status does not mean 'Conferred'.

SELECT h2.solicitation_id as 'SOLICITATION',
case
    when (h2.mod_analise_status_id =9 or h2.mod_analise_status_id =12) then h2.datetime
end
as 'CONFERIDO'
from `mod_analise_historic` h2

Results:

SOLICITATION CONFERRED
25279 (null)
25246 (null)
24842 (null)
25246 2021-06-01T08:47:46Z
25246 (null)
25246 2021-06-01T08:30:00Z

Query 5:

In this way, we obtained the data set that are in the 'Checked' situation and display the date of the conference. Now, since we are only interested in those who are conferred, it should be limited in the clause where, being like this:

SELECT h2.solicitation_id as 'SOLICITATION',
case
    when (h2.mod_analise_status_id =9 or h2.mod_analise_status_id =12) then h2.datetime
end
as 'CONFERIDO'
from `mod_analise_historic` h2
where (h2.mod_analise_status_id =9 or h2.mod_analise_status_id =12)

Note that there are two records for the same solicitation_id, and there may be several others in the case.

Results:

SOLICITATION CONFERRED
25246 2021-06-01T08:47:46Z
25246 2021-06-01T08:30:00Z

Query 6:

Now we have only those who satisfy the expected condition for the second set. But we can observe that, because it is a historical, common situation in many databases, there may be repetitions, or as in the situation in question, more than one status meaning 'conferred', so now just limit the result with a sub-allowance that will bring the earliest date, or longer date as expected result.

Lowest date using function MIN( ):

  and h2.datetime = (Select MIN(datetime)
                                from mod_analise_historic h3
                               where h3.solicitation_id = h2.solicitation_id
                                 and YEAR(h3.datetime) = YEAR(h2.datetime)
                                 and (h3.mod_analise_status_id =9 or h3.mod_analise_status_id =12)
                     )

Higher date using function MAX( ):

  and h2.datetime = (Select MAX(datetime)
                                from mod_analise_historic h3
                               where h3.solicitation_id = h2.solicitation_id
                                 and YEAR(h3.datetime) = YEAR(h2.datetime)
                                 and (h3.mod_analise_status_id =9 or h3.mod_analise_status_id =12)
                     )

Minor elapsed time for conference:

SELECT h2.solicitation_id as 'SOLICITATION',
case
    when (h2.mod_analise_status_id =9 or h2.mod_analise_status_id =12) then h2.datetime
end
as 'CONFERIDO'
from `mod_analise_historic` h2
where (h2.mod_analise_status_id =9 or h2.mod_analise_status_id =12)
  and h2.datetime = (Select MIN(datetime)
                                from mod_analise_historic h3
                               where h3.solicitation_id = h2.solicitation_id
                                 and YEAR(h3.datetime) = YEAR(h2.datetime)
                                 and (h3.mod_analise_status_id =9 or h3.mod_analise_status_id =12)
                     )

Results:

SOLICITATION CONFERRED
25246 2021-06-01T08:30:00Z

Query 7:

Greater elapsed time for conference:

SELECT h2.solicitation_id as 'SOLICITATION',
case
    when (h2.mod_analise_status_id =9 or h2.mod_analise_status_id =12) then h2.datetime
end
as 'CONFERIDO'
from `mod_analise_historic` h2
where (h2.mod_analise_status_id =9 or h2.mod_analise_status_id =12)
  and h2.datetime = (Select MAX(datetime)
                                from mod_analise_historic h3
                               where h3.solicitation_id = h2.solicitation_id
                                 and YEAR(h3.datetime) = YEAR(h2.datetime)
                                 and (h3.mod_analise_status_id =9 or h3.mod_analise_status_id =12)
                     )
                  

Results:

SOLICITATION CONFERRED
25246 2021-06-01T08:47:46Z

Another example using sub-consumption with min() or max(): Subconsultation using Max()
See more about Joins.

  • 1

    You were surgical rsrs.. My scenario is exactly this, I was thinking about how to treat cases where there is more than one status CONFERRED or FORMALIZED (usually by error in the user’s flow or error), but ended up giving me a great solution ^^

Browser other questions tagged

You are not signed in. Login or sign up in order to post.