MySQL - Extract datetime and convert into matrix mapping - mysql

I have huge amount of MySQL record data and must be tranformed like this :
My question is, how to extract datetime value (month, week, hour) and insert it into exact column with binary value (0 or 1) as image above.
PROBLEM SOLVED, i just figured out the easiest way, here for the example:
UPDATE TABLE
SET h1 = CASE WHEN (SELECT DAYOFWEEK (trx_datetime)) = '1' THEN 1
ELSE '0'
END
, h2 = CASE WHEN (SELECT DAYOFWEEK (trx_datetime)) = '2' THEN '1'
ELSE '0'
END
, h3 = CASE WHEN (SELECT DAYOFWEEK (trx_datetime)) = '3' THEN '1'
ELSE '0'
END
, h4 = CASE WHEN (SELECT DAYOFWEEK (trx_datetime)) = '4' THEN '1'
ELSE '0'
END
, h5 = CASE WHEN (SELECT DAYOFWEEK (trx_datetime)) = '5' THEN '1'
ELSE '0'
END
, h6 = CASE WHEN (SELECT DAYOFWEEK (trx_datetime)) = '6' THEN '1'
ELSE '0'
END
, h7 = CASE WHEN (SELECT DAYOFWEEK (trx_datetime)) = '7' THEN '1'
ELSE '0'
END
;

PROBLEM SOLVED, i just figured out the easiest way, here for the example:
UPDATE TABLE
SET h1 = CASE WHEN (SELECT DAYOFWEEK (trx_datetime)) = '1' THEN 1
ELSE '0'
END
, h2 = CASE WHEN (SELECT DAYOFWEEK (trx_datetime)) = '2' THEN '1'
ELSE '0'
END
, h3 = CASE WHEN (SELECT DAYOFWEEK (trx_datetime)) = '3' THEN '1'
ELSE '0'
END
, h4 = CASE WHEN (SELECT DAYOFWEEK (trx_datetime)) = '4' THEN '1'
ELSE '0'
END
, h5 = CASE WHEN (SELECT DAYOFWEEK (trx_datetime)) = '5' THEN '1'
ELSE '0'
END
, h6 = CASE WHEN (SELECT DAYOFWEEK (trx_datetime)) = '6' THEN '1'
ELSE '0'
END
, h7 = CASE WHEN (SELECT DAYOFWEEK (trx_datetime)) = '7' THEN '1'
ELSE '0'
END
;

Related

Can't get CASE and GROUP BY to show all values in the same row

I'm struggling to find a fix for this issue. This is my query:
SELECT
time,
enrolment,
come,
cena,
tipo_ausencia
FROM (
SELECT
DATE_FORMAT(created_at, '%d/%m/%Y') AS time,
enrolment_id as enrolment,
(CASE
WHEN permits.permit_type_id= '4' AND permits.status_id = '2' AND permits.permit_type_option_id='3' AND permits.cancel <1 THEN 'No almuerza'
WHEN permits.permit_type_id= '4' AND permits.status_id = '2' AND permits.permit_type_option_id='4' AND permits.cancel <1 THEN 'Come picnic'
WHEN permits.permit_type_id= '4' AND permits.status_id = '2' AND permits.permit_type_option_id='1' AND permits.cancel <1 THEN 'Almuerza antes'
WHEN permits.permit_type_id= '4' AND permits.status_id = '2' AND permits.permit_type_option_id='2' AND permits.cancel <1 THEN 'Almuerza después'
WHEN permits.permit_type_id= '4' AND permits.status_id = '2' AND permits.permit_type_option_id='5' AND permits.cancel <1 THEN 'Almuerzo con nota'
ELSE null END
) as come,
(CASE
WHEN permits.permit_type_id= '5' AND permits.status_id = '2' AND permits.permit_type_option_id='8' THEN 'No cena'
WHEN permits.permit_type_id= '5' AND permits.status_id = '2' AND permits.permit_type_option_id='9' THEN 'Cena picnic'
WHEN permits.permit_type_id= '5' AND permits.status_id = '2' AND permits.permit_type_option_id='6' THEN 'Cena antes'
WHEN permits.permit_type_id= '5' AND permits.status_id = '2' AND permits.permit_type_option_id='7' THEN 'Cena después'
WHEN permits.permit_type_id= '5' AND permits.status_id = '2' AND permits.permit_type_option_id='10' THEN 'Cena con nota'
ELSE null END
)as cena,
(CASE
WHEN permits.permit_type_id= '6' AND permits.status_id = '2' AND permits.cancel <1 AND DATE(NOW()) between date_start and (date_end-1) THEN 'Duerme fuera'
WHEN permits.permit_type_id= '7' AND permits.status_id = '2' AND permits.cancel <1 AND (date_start = curdate() OR date_end > curdate()) THEN 'Regresa a dormir'
ELSE null END
) as tipo_ausencia
FROM
permits
WHERE (DATE(NOW()) between date_start and (date_end-1) OR (date_start = curdate() OR date_end > curdate())) AND permits.cancel <1
) p
GROUP by 1,2,3,4,5
order by 2 desc
This is the result:
I get 3 rows for the same "enrolment" field. I'm trying to get something like:
time | enrolment | come | cena | tipo_ausencia
19/09/2021 | 101 |no almuerza |no cena | duerme fuera
Any ideas? Thanks!
Use MAX() for converting multiple rows to one row of each enrollment WHERE one column have value others two columns are NULL.
SELECT time
, enrolment
, MAX(come) come
, MAX(cena) cena
, MAX(tipo_ausencia) tipo_ausencia
FROM (
Your main query
) p
GROUP BY time
, enrolment
ORDER BY enrolment desc
Alternative way, no need to use subquery only main query will serve purpose
SELECT DATE_FORMAT(created_at, '%d/%m/%Y') AS time
, enrolment_id as enrolment
, MAX(case logic for come place here) as come
, MAX(case logic for cena place here) as cena
, MAX(case logic for tipo_ausencia place here) as tipo_ausencia
FROM permits
WHERE (DATE(NOW()) between date_start and (date_end-1) OR (date_start = curdate() OR date_end > curdate()))
AND permits.cancel <1
GROUP BY DATE_FORMAT(created_at, '%d/%m/%Y')
, enrolment_id
ORDER BY enrolment_id DESC
More readable CASE statement for come. If data type of permit_type_id, status_id and permit_type_option_id are integer then not to use quation mark.
CASE
WHEN permit_type_id = '4' AND status_id = '2' AND cancel < 1
THEN CASE permit_type_option_id
WHEN '3' THEN 'No almuerza'
WHEN '4' THEN 'Come picnic'
WHEN '1' THEN 'Almuerza antes'
WHEN '2' THEN 'Almuerza después'
WHEN '5' THEN 'Almuerzo con nota'
END
ELSE NULL
END

MySQL grouping giving 4 rows instead of 1

I'm having a hard time getting the rows to group like needed. It gives me 4 rows instead of 1. I'm sure it's something simple, but I can't figure it out.
SELECT DISTINCT
th.name Serial,
CASE WHEN td.parameter = 4854455 THEN TRIM(LEADING '0' FROM td.text) ELSE NULL END Auto_PF,
CASE WHEN td.parameter = 797902 THEN TRIM(LEADING '0' FROM td.text) ELSE NULL END Auto_IC,
CASE WHEN td.parameter = 797402 THEN TRIM(LEADING '0' FROM td.text) ELSE NULL END Auto_NIC,
CASE WHEN td.parameter = 4854430 THEN TRIM(LEADING '0' FROM td.text) ELSE NULL END Auto_E46
FROM thisdata td
INNER JOIN this th
ON td.thisid = th.id
WHERE td.parameter IN ('4854455', '797902', '797402', '4854430', '6332168',
'6332160', '798102', '12000003', '12020956', '12020947', '12015253')
AND td.created >= (NOW() - INTERVAL 1 MONTH)
GROUP BY Serial, td.parameter, td.text
...
Result1
I think you should be aggregating only by the name, and then pivoting the CASE expressions:
SELECT
th.name Serial,
MAX(CASE WHEN td.parameter = 4854455 THEN TRIM(LEADING '0' FROM td.text) END) Auto_PF,
MAX(CASE WHEN td.parameter = 797902 THEN TRIM(LEADING '0' FROM td.text) END) Auto_IC,
MAX(CASE WHEN td.parameter = 797402 THEN TRIM(LEADING '0' FROM td.text) END) Auto_NIC,
MAX(CASE WHEN td.parameter = 4854430 THEN TRIM(LEADING '0' FROM td.text) END) Auto_E46
FROM thisdata td
INNER JOIN this th
ON td.thisid = th.id
WHERE
td.parameter IN ('4854455', '797902', '797402', '4854430', '6332168', '6332160',
'798102', '12000003', '12020956', '12020947', '12015253') AND
td.created >= (NOW() - INTERVAL 1 MONTH)
GROUP BY
th.name;

SUM and GROUP BY diferent columns

I need to group the sum by different columns:
SUM1 group by Banco_Recarga
SUM2 group by BancoRetiro
SELECT Banco_Recarga, BancoRetiro, bancos_recargas.banco,
SUM(CASE WHEN Tipo='1' AND (Status = '1' OR Status = '2') THEN '1' ELSE 0 END) AS SUM1,
SUM(CASE WHEN Tipo='2' AND (Status = '1' OR Status = '2') THEN '1' ELSE 0 END) AS SUM2
FROM transaccionesrr
INNER JOIN bancos_recargas ON (transaccionesrr.Banco_Recarga = bancos_recargas.id)
WHERE Fecha_Recarga BETWEEN '2017-11-01' AND '2017-11-10' GROUP BY Banco_Recarga ORDER BY SUM1;
I have been looking for hours but i can't find a solution
Try this:
SELECT
CASE
WHEN Tipo = '1' AND (Status = '1' OR Status = '2') THEN Banco_Recarga
WHEN Tipo = '2' AND (Status = '1' OR Status = '2') THEN BancoRetiro
ELSE 'Unexpected'
END AS banco
, SUM(CASE WHEN Tipo = '1' AND (Status = '1' OR Status = '2') THEN '1' ELSE 0 END) AS sum1
, SUM(CASE WHEN Tipo = '2' AND (Status = '1' OR Status = '2') THEN '1' ELSE 0 END) AS sum2
FROM transaccionesrr
INNER JOIN bancos_recargas ON (transaccionesrr.Banco_Recarga = bancos_recargas.id)
WHERE Fecha_Recarga BETWEEN '2017-11-01' AND '2017-11-10'
GROUP BY
CASE
WHEN Tipo = '1' AND (Status = '1' OR Status = '2') THEN Banco_Recarga
WHEN Tipo = '2' AND (Status = '1' OR Status = '2') THEN BancoRetiro
ELSE 'Unexpected'
END
ORDER BY sum1, sum2
You may need to add conditions into the where clause.

mysql combining two tables to produce the following output

hello i had ask the same question before but i want another way. we can use locate and max function to solve the question. but my teacher told me to do like this
my code is like this when '0' then '1' else '0'
select u.id, u.name,
case f.finger when '0' then '1' else '0' end as '0',
case f.finger when '1' then '1' else '0' end as '1',
case f.finger when '2' then '1' else '0' end as '2',
case f.finger when '3' then '1' else '0' end as '3',
case f.finger when '4' then '1' else '0' end as '4',
case f.finger when '5' then '1' else '0' end as '5'
from users u left join user_fingerprints f
on u.id= f.user_id
the code above will resulted in 8 rows.
then i need to combine the rows so that the rows with the same id combine to produce this
from that result then use case function. when the value is 1 then y. when value is zero then n.
can someone give me the answer without the use of max function? thanks
the table and result
You can also do it with SUM() and another CASE EXPRESSION :
SELECT t.id,t.name,
CASE WHEN t.`0` > 0 THEN 'Y' ELSE 'N' as `0`
CASE WHEN t.`1` > 0 THEN 'Y' ELSE 'N' as `1`
....
FROM (
SELECT u.id,u.name,
SUM(CASE WHEN f.finger = '0' then '1' else '0' end) as `0`,
SUM(CASE WHEN f.finger = '1' then '1' else '0' end) as `1`,
....
from users u left join user_fingerprints f
on u.id= f.user_id
GROUP BY u.id,u.name) t

What is wrong is this mysql statement with case?

SELECT COUNT(*)
FROM PATIENTS A, RECALLS_AFTER_RESERV C
LEFT JOIN PATIENT_LAST_RESERV D
ON D.PATIENT_ID = C.PATIENT_ID
WHERE C.PATIENT_ID = A.ID
AND C.OFFICE_ID = A.OFFICE_ID
AND C.OFFICE_ID = ?
AND YEAR(CONVERT_TZ(C.RECALLS_AT, 'UTC', 'Asia/Tokyo')) = ?
AND (CASE
WHEN ISNULL(D.STARTS_AT) THEN
A.CHECKED_IN_AT
ELSE
D.STARTS_AT
END) >= CONVERT_TZ('2015-01-27 00:00:00', 'Asia/Tokyo', 'UTC')) AND (CASE
WHEN ISNULL(D.STARTS_AT) THEN
A.CHECKED_IN_AT
ELSE
D.STARTS_AT
END) <= CONVERT_TZ('2015-01-27 23:59:59', 'Asia/Tokyo', 'UTC') AND C.RECALLED_AT IS NULL AND C.STARTS_AT IS NULL
I want to use the case to determine whether the D.starts_at have value,if not, I use A.checked_in_at to replace the D.starts_at.but it gives an error
(case when isnull(D.starts_at) then A.checked_in_at else D.starts_at end) >= CONVERT_TZ('2015-01-27 00:00:00', 'Asia/Tokyo', 'UTC') )
I finally find the problem, the case statement is right. the problem is the redundant ) in the above.