有没有更简单的方法来进行此查询?
Is there an easier way to make this query?
我有两个不同的 table 来自名为 "empleados" 和 "fichajes" 的数据库。 empleados 有员工数据,fichajes 有他们开始工作的日期和时间。
我想获得特定员工在两个日期之间完成的总工作时间,比方说从 20 日到 29 日。
我有一个在 C# 上与 Dapper 一起使用的查询:
SELECT CONCAT(e.nombre, " " ,e.apellido) as fullName, tfichajes.total
FROM empleados e
INNER JOIN (
SELECT f1.nif,
SEC_TO_TIME(SUM(TIME_TO_SEC(f1.fechasalida) - TIME_TO_SEC(f1.fechaentrada))) AS total
FROM fichajes f1
WHERE f1.fechasalida <= '2019-04-29'
and f1.fechaentrada >= '2019-04-20'
GROUP BY f1.nif
) AS tfichajes
ON e.nif = tfichajes.nif
WHERE e.nif = '33333333P'
这很好用,但我想知道是否可以简化它。
这是我程序中的代码:
public static List<string> CalculaTotalHoras(string nif, DateTime fechaEntrada, DateTime fechaSalida)
{
var dbCon = DBConnection.Instancia();
if (dbCon.Conectado())
{
string format = "yyyy-MM-dd";
List<string> result = new List<string>();
using (IDbConnection conexion = dbCon.Conexion)
{
var output = conexion.Query($"SELECT CONCAT(e.nombre, \" \" ,e.apellido) as fullName, tfichajes.total " +
$"FROM empleados e INNER JOIN (SELECT f1.nif, SEC_TO_TIME(SUM(TIME_TO_SEC(f1.fechasalida) - TIME_TO_SEC(f1.fechaentrada))) AS total " +
$"FROM fichajes f1 where f1.fechasalida <= '{fechaSalida.ToString(format)}' and f1.fechaentrada >= '{fechaEntrada.ToString(format)}' GROUP BY f1.nif) " +
$"as tfichajes ON e.nif = tfichajes.nif where e.nif = '{ nif }';").ToList();
var i = 0;
foreach (IDictionary<string, object> row in output)
{
foreach (var pair in row)
{
if (i == 0)
{
result.Add(pair.Value.ToString());
i++;
}
else
{
result.Add(pair.Value.ToString());
}
}
}
return result;
}
}
else return null;
}
如果您对代码的可读性有疑问 here,那么您有一个 gyazo。
Workingtime fichajes
table and employees empleados
table.
使用那个确切的查询,预期结果是 Alvaro Arguelles 00:05:00
,在代码中,我想在 result
列表中将 Alvaro Arguelles
和 00:05:00
分开。
我是不是让它比实际更难了?
您的查询可以大大简化。您的内部查询正在选择在相关日期工作的所有员工,我将从 INNER 查询开始作为主要 FROM table 获取一名员工的数据。 THEN加入员工抢名。
select
CONCAT(e.nombre, " " ,e.apellido) as fullName,
OneEmp.Total
from
( select
f1.nif,
SEC_TO_TIME( SUM(TIME_TO_SEC(f1.fechasalida)
- TIME_TO_SEC(f1.fechaentrada))) AS total
from
fichajes f1
where
f1.nif = '33333333P'
AND f1.fechasalida >= '2019-04-20'
AND f1.fechasalida <= '2019-04-29' ) OneEmp
JOIN empleados e
on OneEmp.nif = e.nif
由于您的查询是按一名员工汇总的,因此无论如何它只会 return 一行。所以上面的查询将 return 1 行,2 列...名称和总计。应该能够直接读回这两个值。
但正如其他人评论的那样,参数化您的查询调用。
我有两个不同的 table 来自名为 "empleados" 和 "fichajes" 的数据库。 empleados 有员工数据,fichajes 有他们开始工作的日期和时间。
我想获得特定员工在两个日期之间完成的总工作时间,比方说从 20 日到 29 日。
我有一个在 C# 上与 Dapper 一起使用的查询:
SELECT CONCAT(e.nombre, " " ,e.apellido) as fullName, tfichajes.total
FROM empleados e
INNER JOIN (
SELECT f1.nif,
SEC_TO_TIME(SUM(TIME_TO_SEC(f1.fechasalida) - TIME_TO_SEC(f1.fechaentrada))) AS total
FROM fichajes f1
WHERE f1.fechasalida <= '2019-04-29'
and f1.fechaentrada >= '2019-04-20'
GROUP BY f1.nif
) AS tfichajes
ON e.nif = tfichajes.nif
WHERE e.nif = '33333333P'
这很好用,但我想知道是否可以简化它。
这是我程序中的代码:
public static List<string> CalculaTotalHoras(string nif, DateTime fechaEntrada, DateTime fechaSalida)
{
var dbCon = DBConnection.Instancia();
if (dbCon.Conectado())
{
string format = "yyyy-MM-dd";
List<string> result = new List<string>();
using (IDbConnection conexion = dbCon.Conexion)
{
var output = conexion.Query($"SELECT CONCAT(e.nombre, \" \" ,e.apellido) as fullName, tfichajes.total " +
$"FROM empleados e INNER JOIN (SELECT f1.nif, SEC_TO_TIME(SUM(TIME_TO_SEC(f1.fechasalida) - TIME_TO_SEC(f1.fechaentrada))) AS total " +
$"FROM fichajes f1 where f1.fechasalida <= '{fechaSalida.ToString(format)}' and f1.fechaentrada >= '{fechaEntrada.ToString(format)}' GROUP BY f1.nif) " +
$"as tfichajes ON e.nif = tfichajes.nif where e.nif = '{ nif }';").ToList();
var i = 0;
foreach (IDictionary<string, object> row in output)
{
foreach (var pair in row)
{
if (i == 0)
{
result.Add(pair.Value.ToString());
i++;
}
else
{
result.Add(pair.Value.ToString());
}
}
}
return result;
}
}
else return null;
}
如果您对代码的可读性有疑问 here,那么您有一个 gyazo。
Workingtime fichajes
table and employees empleados
table.
使用那个确切的查询,预期结果是 Alvaro Arguelles 00:05:00
,在代码中,我想在 result
列表中将 Alvaro Arguelles
和 00:05:00
分开。
我是不是让它比实际更难了?
您的查询可以大大简化。您的内部查询正在选择在相关日期工作的所有员工,我将从 INNER 查询开始作为主要 FROM table 获取一名员工的数据。 THEN加入员工抢名。
select
CONCAT(e.nombre, " " ,e.apellido) as fullName,
OneEmp.Total
from
( select
f1.nif,
SEC_TO_TIME( SUM(TIME_TO_SEC(f1.fechasalida)
- TIME_TO_SEC(f1.fechaentrada))) AS total
from
fichajes f1
where
f1.nif = '33333333P'
AND f1.fechasalida >= '2019-04-20'
AND f1.fechasalida <= '2019-04-29' ) OneEmp
JOIN empleados e
on OneEmp.nif = e.nif
由于您的查询是按一名员工汇总的,因此无论如何它只会 return 一行。所以上面的查询将 return 1 行,2 列...名称和总计。应该能够直接读回这两个值。
但正如其他人评论的那样,参数化您的查询调用。