我试图从2个表中获得一些结果,它们是1 to n
关系。我想从一个表Extensao
获得2列,从第二个表HorarioExtensao
获得一个结果。我试图按月过滤,但我只想考虑第二列的较低日期,因为相同的结果可能有不同月份的多个日期。
我已经尝试在HorarioExtensao
上进行查询,然后使用SELECT
执行另一个MIN(h.hora) BETWEEN $inicial and $final
,但问题在于我不知道在哪里放INNER JOIN
Extensao
选择e.nome
和e.codigo
。提前谢谢。
$mes = $_GET["mes"];
$ano = $_GET["ano"];
$inicial = date("Y/m/d g:i:s",mktime(0,0,0,$mes,1,$ano));
$final = date("Y/m/t g:i:s",mktime(0,0,0,$mes,1,$ano));
$db = pg_connect("host=localhost dbname=saga user=**** password=****");
$result = pg_query($db,"SELECT e.nome, MIN(h.hora), e.codigo
FROM Extensao e
INNER JOIN HorarioExtensao h ON h.idExtensao = e.idExtensao
WHERE h.hora BETWEEN
to_timestamp('$inicial','YYYY/MM/DD HH:MI:SS') AND
to_timestamp('$final','YYYY/MM/DD HH:MI:SS')
GROUP BY 3,1");
在桌子上:
- Extensao
---------------------- | ID | NOME | CODIGO | |----|------|--------| | 1 | N1 | 201 | | 2 | N2 | 223 | | 3 | N3 | 266 | ----------------------
- HorarioExtensao
--------------------------- | idExtensao | hora | |------------|------------| | 1 | 2012-01-21 | | 1 | 2012-01-22 | | 1 | 2012-02-15 | | 1 | 2012-02-16 | ---------------------------
如果我尝试选择月2
,我不希望得到任何结果,因为相同idExtensao
的较低日期是第1个月。如果我选择月{{1} },我想只得到1个结果,应该是1
。另外,我知道N1,2012-01-21,201
不是2012-01-21
,我只是简化。
答案 0 :(得分:1)
这个问题留下了解释的余地,礼貌地说。
我认为这可能就是您要找的内容:预聚合表上的LEFT [OUTER ] JOIN
:
SELECT e.nome, h.min_hora, e.codigo
FROM extensao e
LEFT JOIN (
SELECT idextensao, min(hora) AS min_hora
FROM horarioextensao
GROUP BY 1
) h ON h.idextensao = e.id
AND h.min_hora >= to_timestamp($inicial, 'YYYY/MM/DD HH:MI:SS')
AND h.min_hora < to_timestamp($final, 'YYYY/MM/DD HH:MI:SS');
在子查询h
中,我在加入hora
之前从idextensao
中选择最早的horarioextensao
extensao
。
另请注意我如何将WHERE
条件提升为LEFT JOIN
条件。这样,您就可以获得extensao
中的所有行以及horarioextensao
中符合条件的所有行。
如果您只想要JOIN
中匹配extensao
的行,请更改为普通min_hora
。在这种情况下,条件可以保留在WHERE
子句中。
您示例中的1月结果为:
nome | min_hora | codigo
-----+------------+---------
N1 | 2012-01-21 | 201
N2 | null | 223
N3 | null | 266
二月:
nome | min_hora | codigo
-----+------------+---------
N1 | null | 201
N2 | null | 223
N3 | null | 266
答案 1 :(得分:0)
尝试使用此SQL Server语法 - 您需要翻译它,但它应该提供正确的想法
SELECT e.nome,MIN(h.hora),e.codigo
FROM Extensao e
CROSS APPLY
(SELECT TOP(1) h.hora
FROM HorarioExtensao h
WHERE h.idExtensao = e.idExtensao
AND
h.hora >= to_timestamp('$inicial','YYYY/MM/DD HH:MI:SS')
AND
h.hora < to_timestamp('$final','YYYY/MM/DD HH:MI:SS')
ORDER BY h.hora)
GROUP BY 3,1