I am preparing a query in which the total to be paid is added to the number of daily libraries that a student requests throughout the month.
It is worth mentioning that there are several types of libraries and what I need is to be able to associate the document payable to the game library catch of that month depending on the type of library
So, if a student requested 5 libraries in the month and 2 are morning and 3 are sports. 2 documents payable would be created and the morning document payable would be assigned to the 2 captures and the sports document to the 3 captures of the month.
CREATE PROCEDURE pagodeludotecaalumnos (IN alumnoid, IN fecha) BEGIN
insert into cj_documentoporpagar(documentoid, subconceptoid, pagoestatusid, alumnoid, cicloid, gradoid,
mediopagoid, importe, saldo, fechalimitepago, fechacreacion, fechaprontopago, referencia, documento,
hermanos, reingreso, padreexalumno, concepto, iva)
select 17 as DocumentoId,
case when a.TipoId = 1 or a.tipoid = 2 then 122
when a.TipoId = 3 then 235
when a.TipoId = 4 then -1 end as SubConceptoId,
1 as PagoEstatusId, b.AlumnoId,
5 as CicloId, b.GradoId, 1 as MedioPagoId,
case when c.PrimerNombre like '%*%' or c.ApellidoPaterno like '%*%' or c.ApellidoMaterno like '%*%' then 40 * Count(*) else 55 * Count(*) end as Importe,
case when c.PrimerNombre like '%*%' or c.ApellidoPaterno like '%*%' or c.ApellidoMaterno like '%*%' then 40 * Count(*) else 55 * Count(*) end as Saldo,
DATE(DATE_ADD(LAST_DAY(fecha), INTERVAL 1 MONTH)) as FechaLImitePago, now() as FechaCreacion, now() as FechaProntoPago,
'' as Referencia, '202003L' as documento, 0 as Hermanos, 0 as Reingreso, 0 as PadreExAlumno,
Concat('Ludoteca Marzo (', cast(Count(*) as int), ') dia(s)') as Concepto, 0 as IVA
/*, Concat(c.PrimerNombre, ' ', c.ApellidoPaterno, ' ', c.ApellidoMaterno) AlumnoNombre*/
from lu_captura a
inner join ce_alumnoporciclo b on a.alumnoporcicloid = b.alumnoporcicloid
inner join ce_alumno c on b.alumnoid = c.alumnoid
where date(a.Fecha) between DATE_FORMAT(fecha, '%Y-%m-01') and LAST_DAY(fecha) and a.TieneContrato = 0 and c.alumnoid = alumnoid
group by a.TipoId, b.AlumnoId, b.GradoId
SET #LID = LAST_INSERT_ID();
update lu_captura set DocumentoPorPagarId = #LID where Fecha between DATE_FORMAT(fecha, '%Y-%m-01') and LAST_DAY(fecha)
Currently I have this query and the question is: How could I relate the document payable created to the corresponding type of library?
According to MySQL Stored Procedure
I am using this syntax in stored procedure if you work in the same
then you can try this
DROP Procedure IF EXISTS pagodeludotecaalumnos;
Delimitter to used to set whole procedure below it as single operationable
DELIMITER $$
Create procedure command
CREATE PROCEDURE pagodeludotecaalumnos (
IN alumnoid int, IN fecha varchar(50), IN_action char(30)
)
Case begin from here
BEGIN
**-- switch case begin here**
CASE
WHEN IN_action = "insert" THEN
Creating entry for new record
INSERT INTO cj_documentoporpagar(
documentoid, subconceptoid,pagoestatusid, alumnoid, cicloid,
gradoid,mediopagoid, importe,saldo, fechalimitepago, fechacreacion,
fechaprontopago, referencia,documento,hermanos, reingreso,
padreexalumno, concepto, iva
)
VALUES(
IN_documentoid, IN_subconceptoid, IN_pagoestatusid,
IN_alumnoid,IN_cicloid,IN_gradoid, IN_mediopagoid, IN_importe,
IN_saldo,IN_fechalimitepago, IN_fechacreacion,IN_fechaprontopago,
IN_referencia, IN_documento, IN_hermanos, IN_reingreso,
IN_padreexalumno, IN_concepto, IN_iva
);
-- Insert end here
For update
WHEN IN_action = "update" THEN
-- For update elements
-- I am only show you how i make stored procedure in mysql i.e. your update statement
UPDATE lu_captura SET DocumentoPorPagarId = #LID where Fecha between
DATE_FORMAT(fecha, '%Y-%m-01') and LAST_DAY(fecha)
WHERE condition(if_exists);
For select statement
-- For Select elements
-- i.e. your select statement because i don't know what are you want to update, store an insert
WHEN IN_action = "select" THEN
select 17 as DocumentoId,
case when a.TipoId = 1 or a.tipoid = 2 then 122
when a.TipoId = 3 then 235
when a.TipoId = 4 then -1 end as
SubConceptoId,
1 as PagoEstatusId, b.AlumnoId,
5 as CicloId, b.GradoId, 1 as MedioPagoId,
case when c.PrimerNombre like '%*%' or c.ApellidoPaterno
like '%*%' or c.ApellidoMaterno
like '%*%' then 40 * Count(*)
else 55 * Count(*) end as Importe,
case
when c.PrimerNombre like '%*%' or c.ApellidoPaterno
like '%*%' or c.ApellidoMaterno
like '%*%' then 40 * Count(*) else 55 * Count(*)
end as Saldo,
DATE(DATE_ADD(LAST_DAY(fecha), INTERVAL 1 MONTH)) as
FechaLImitePago, now() as FechaCreacion, now() as
FechaProntoPago, '' as Referencia, '202003L' as documento, 0
as Hermanos, 0 as Reingreso, 0 as PadreExAlumno,
Concat('Ludoteca Marzo (', cast(Count(*) as int), ') dia(s)')
as Concepto, 0 as IVA
/*, Concat(c.PrimerNombre, ' ', c.ApellidoPaterno, ' ',
c.ApellidoMaterno) AlumnoNombre*/
from lu_captura a
inner join ce_alumnoporciclo b on a.alumnoporcicloid =
b.alumnoporcicloid
inner join ce_alumno c on b.alumnoid = c.alumnoid
where
date(a.Fecha) between DATE_FORMAT(fecha, '%Y-%m-01') and
LAST_DAY(fecha) and a.TieneContrato = 0 and c.alumnoid =
alumnoid group by a.TipoId, b.AlumnoId, b.GradoId
END CASE;
-- switch case ends here
END;
-- end of the PROCEDURE
I want to retrieve columns name from table whose value is 1
My query is give below...
mysqli_query($conn,"SELECT * FROM `tbl_therapist_schedule` WHERE `schedule_date`='30.11.2017'");
My table structure is give below...
slot1 slot2 slot3
1 1 0
2 1 1
1 1 2
3 1 0
my result...
slot1 slot2 slot3
I have the serious feeling that your data is not normalized. Instead of having separate columns for each slot, I would store all this data in a single column with metadata to relate each slot's state.
That being said, one way to get the output you want would be to aggregate over each slot column and check for the presence/absence of at least one 1 value. I then use GROUP_CONCAT to generate a CSV list of matching slots.
SELECT GROUP_CONCAT(slots)
FROM
(
SELECT
CASE WHEN SUM(CASE WHEN slot1 = 1 THEN 1 ELSE 0 END) > 0
THEN 'slot1' END AS slots
FROM tbl_therapist_schedule
WHERE schedule_date = '30.11.2017'
UNION ALL
SELECT
CASE WHEN SUM(CASE WHEN slot2 = 1 THEN 1 ELSE 0 END) > 0
THEN 'slot2' END
FROM tbl_therapist_schedule
WHERE schedule_date = '30.11.2017'
UNION ALL
SELECT
CASE WHEN SUM(CASE WHEN slot3 = 1 THEN 1 ELSE 0 END) > 0
THEN 'slot3' END
FROM tbl_therapist_schedule
WHERE schedule_date = '30.11.2017'
) t;
Demo
We have the table structure like
Fieldid userid data
41 2 1
12 2 0
41 3 1
12 3 1
We want the user which have (data=1 and filedid = 41) and (data = 0 and filedid=12)
We tried the query
select userid from table
where (data=1 and filedid = 41)
AND (data = 0 and filedid=12)
but it returns empty results.
Can anyone help how we will get the record using MySQL?
You can use grouping with a conditional aggregate in the HAVING clause:
SELECT userid
FROM mytable
GROUP BY userid
HAVING COUNT(CASE WHEN data = 1 AND FieldId = 1 THEN 1 END) >= 1 AND
COUNT(CASE WHEN data = 0 AND FieldId = 12 THEN 1 END) >= 1
you need to use union all like:
select * from table1 where Fieldid = 41 and data = 1 union all
select * from table1 where Fieldid = 12 and data = 0
attached image shows the output
Similar to #Giorgos, with multicolumn compare for conciseness:
select userid
from t
group by userid
having sum((data,fieldId) = (1, 41)) > 0
and sum((data,fieldId) = (0, 12)) > 0
When searching for results with one or another set of data you have to use OR keyword, not AND.
SELECT userid FROM table
WHERE (data = 1 AND filedid = 41)
OR (data = 0 AND filedid = 12)
I have a table containing the following data columns:
ord_number check
OR123 0
OR125 1
OR123 2
OR123 0
OR124 0
OR124 0
OR125 0
OR123 0
The check column indicates if we have fully supplied the order line with a value of zero or below meaning 'yes we have supplied complete' and a value of 1 or above meaning 'no we have not supplied complete' .
To calculate an order fill rate (how many orders have been filled complete) I need to know how many of the orders have only zero check results for each entry and how many have at least one positive check result.
My logic is that I need to GROUP the items and then carry out a COUNTIF within the group (this may be the wrong SQL methodology but logically it makes sense to me in terms of the outcome I'm looking for). From this query I need to return those two values into my PHP script.
The results from this data set would be:
Complete = 1 (orders with only zero checks)
Incomplete = 2 (orders where one or more lines have positive checks)
I've spent the morning trying to find a solution but can't find anything that I either understand enough or is similar enough that I can break it down and understand it.
If someone can help me by pointing me in the right direction or can provide a sample with an explanation I would be very grateful.
For 1 row with 2 counter fields use:
SELECT
SUM(CASE WHEN `check` = 1 THEN 1 ELSE 0 END) AS incomplete,
SUM(CASE WHEN `check` = 0 THEN 1 ELSE 0 END) AS complete
FROM orders
For 2 rows with 1 name use:
SELECT COUNT(`ord_number`) AS fulfillment
FROM orders WHERE (`check`=0)
UNION SELECT COUNT(ord_number)
FROM orders WHERE (`check`=1)
in which case you need to put row 1 into $complete (check=0)
and row 2 into $incomplete (check=1)
you may add:
UNION SELECT COUNT(ord_number) FROM orders
which will give you the total records on row 3.
output will be:
SELECT * FROM orders
ord_number check
---------------------
OR123 0
OR124 1
OR125 0
OR126 0
OR127 0
OR123 0
OR125 1
SELECT COUNT(`ord_number`) AS counts FROM orders or1 WHERE (`check`=0)
UNION SELECT COUNT(ord_number) FROM orders or2 WHERE (`check`=1)
UNION SELECT COUNT(ord_number) FROM orders
counts
-------
5
2
7
SELECT
SUM(CASE WHEN `check` = 1 THEN 1 ELSE 0 END) AS incomplete,
SUM(CASE WHEN `check` = 0 THEN 1 ELSE 0 END) AS complete FROM orders
incomplete complete
-------------------------
2 5
As for PHP:
for 1 row:
mysql_select_db($database_test, $test);
$query_countIn1Row = " SELECT SUM(CASE WHEN `check` = 1 THEN 1 ELSE 0 END) AS
incomplete,
SUM(CASE WHEN `check` = 0 THEN 1 ELSE 0 END) AS complete
FROM orders";
$countIn1Row = mysql_query($query_countIn1Row, $test) or die(mysql_error());
do {
$varIncomplete = $row_countIn1Row['incomplete'];
$varComplete = $row_countIn1Row['complete'];
} while ($row_countIn1Row = mysql_fetch_assoc($countIn1Row));
and for 1 column with counts:
mysql_select_db($database_test, $test);
$query_countOrders = "SELECT COUNT(`ord_number`) AS counts
FROM orders or1 WHERE (`check`=0)
UNION SELECT COUNT(ord_number) FROM orders or2 WHERE (`check`=1)
UNION SELECT COUNT(ord_number) FROM orders";
$countOrders = mysql_query($query_countOrders, $test) or die(mysql_error());
$myCounts = array();
do {
$myCounts[]= $row_countOrders['counts'];
} while ($row_countOrders = mysql_fetch_assoc($countOrders));
$complete = $myCounts[0];
$incomplete = $myCounts[1];
$total = $myCounts[2];
SELECT ord_number,IF(MAX( check) <=0 ,'COMPLETED','PENDING')
from TABLENAME
group by (ord_number )
Through this oneline query you will easily get which order is in pending status and which one is complete status
AS per your given details
The check column indicates if we have fully supplied the order line
with a value of zero or below meaning 'yes we have supplied complete'
and a value of 1 or above meaning 'no we have not supplied complete' .
it means check column can contain negative value as well as 0 for indicating the complete status and 1 or any postive integer number to indicate the pending status.
so the logic should be find the max(check) so if the max for a order is found 0 or any negative number then we will sure that order is complete and if it found a positive number it means there was a pending entry.
You can do this in two steps:
SELECT ord_number,
SUM(CASE WHEN `check` = 0 THEN 1 ELSE 0 END) as Comp,
COUNT(`check`) as total
FROM tab1
GROUP BY ord_number
This would give you the number of rows with 0 (complete) and the total number of rows for each ord_number.
Then you do a COUNT to validate when those two are equal:
SELECT CASE WHEN comp = total THEN 'COMPLETE' ELSE 'INCOMPLETE' END AS status,
COUNT(*) AS statusCount
FROM(
SELECT ord_number,
SUM(CASE WHEN `check` = 0 THEN 1 ELSE 0 END) as Comp,
COUNT(`check`) as total
FROM tab1
GROUP BY ord_number) a
GROUP BY 1;
This should get you what you want.
sqlfiddle demo
Note that i used ` around check since this is a mysql reserved word
Suppose I have a table:
col1, col2, col3
1 0 1.3
0 0 0
0 1 0
1 1.5 1
Now, let's say each row has a "weight" calculated as this:
(col1 > 0 ? 1 : 0) + (col2 > 0 ? 1 : 0) + (col3 > 0 ? 1 : 0)
How can I select the total weight of all rows?
With the data I have given the total weight is 2+0+1+3=6
You just need one aggregate SUM() surrounding all the conditions with no GROUP BY.
SELECT
SUM(
(CASE WHEN col1 > 0 THEN 1 ELSE 0 END)
+ (CASE WHEN col2 > 0 THEN 1 ELSE 0 END)
+ (CASE WHEN col3 > 0 THEN 1 ELSE 0 END)
) AS total_weight
FROM your_table
http://sqlfiddle.com/#!2/b0d82/1
I am using CASE WHEN... here as it is portable across any RDBMS. Since MySQL will return a boolean 0 or 1 for the conditions though, it can be simplified in MySQL as:
SELECT
SUM(
(col1 > 0) /* returns 1 or 0 */
+ (col2 > 0)
+ (col3 > 0)
) AS total_weight
FROM your_table
http://sqlfiddle.com/#!2/b0d82/2