获取SQL表另一列对应的行记录
Posted
技术标签:
【中文标题】获取SQL表另一列对应的行记录【英文标题】:Get corrosponding record Of Row in Another Column of SQL Table 【发布时间】:2019-08-05 13:20:15 【问题描述】:我有一个 SQL 表,其中存储/保存了员工每天的记录我想以表格格式获得该结果
考虑如下所示的表格
NAME | DATEANDTIME | ACTION
----------|---------------------|-----------
JOHN | 2019-07-07 10:00:00 | INTIME
JOHN | 2019-07-07 18:00:00 | OUTTIME
WILLIAM | 2019-07-07 10:02:00 | INTIME
CATHERIN | 2019-07-07 10:10:00 | INTIME
JOHN | 2019-07-07 13:00:00 | LUNCH
CATHERIN | 2019-07-07 18:30:00 | OUTTIME
CATHERIN | 2019-07-07 14:30:00 | LUNCH
WILLIAM | 2019-07-07 19:14:00 | INTIME
我希望上面的表格以垂直格式显示,因为它应该按名称分组
我曾尝试使用数据透视查询,但它没有给我预期的输出
select
Dateandtime,
[name],
[action]
from
(
select Dateandtime,
[name],
[action]
from
table1) a pivot(max(action) for tagindex in (Dateandtime,
[name],
[action]))pvt
INTIME | OUTTIME | LUNCH | NAME
---------------------|-----------------------|---------------------|--------
#2019-07-07 10:00:00 | 2019-07-07 18:00:00 | ------- | WILLIAM
#2019-07-07 10:10:00 | 2019-07-07 18:30:00 | 2019-07-07 14:30:00 |CATHERIN
【问题讨论】:
考虑处理应用代码中数据显示的问题。 顺便说一句,我认为标题与问题没有任何关系。 鉴于数据集是动态的,列应该以什么顺序出现? 【参考方案1】:假设每个人的每种类型最多有一行,您可以使用条件聚合来做到这一点:
select name,
max(case when action = 'INTIME' then dateandtime end) as intime,
max(case when action = 'OUTTIME' then dateandtime end) as outtime,
max(case when action = 'LUNCH' then dateandtime end) as lunch
from t
group by name;
如果给定名称有多个值,我建议您提出一个新问题,详细说明如何处理这种情况。
【讨论】:
感谢您的即时回复,但动作可以是完全动态的,这只是我给出的 3 个场景,还有更多,比如请假、休息、会议、茶歇等等 如何动态处理同样,这是一天的场景,如果有说周的记录,这个查询将如何使用这个 使用pivot,你不能有动态的列数,除非你生成动态sql然后使用sp_executeSQL。但此时您的列数是可变的,因此您的下游报告/网页必须支持它。 @LALITACHAREKAR 。 . .然后你需要动态SQL。您可以查找正在使用的数据库的示例。 select name,dob,city max(case when action = 'INTIME' then dateandtime end) as intime, max(case when action = 'OUTTIME' then dateandtime end) as outtime, max(case when action = 'LUNCH' then dateandtime end) as lunch from t group by name;【参考方案2】:考虑以下,它使用应用程序代码来处理数组的旋转/重新排列...
<?php
/*
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id SERIAL PRIMARY KEY
,name VARCHAR(12) NOT NULL
,dt DATETIME NOT NULL
,action VARCHAR(12) NOT NULL
);
INSERT INTO my_table VALUES
(1,'John' ,'2019-07-07 10:00:00','in'),
(2,'John' ,'2019-07-07 18:00:00','out'),
(3,'William' ,'2019-07-07 10:02:00','in'),
(4,'Catherine','2019-07-07 10:10:00','in'),
(5,'John' ,'2019-07-07 13:00:00','lunch'),
(6,'Catherine','2019-07-07 18:30:00','out'),
(7,'Catherine','2019-07-07 14:30:00','lunch'),
(8,'William' ,'2019-07-07 19:14:00','in');
*/
require('path/to/connnection/stateme.nts');
$query = "
SELECT id
, name
, dt
, action
FROM my_table
ORDER
BY name
, action;
";
$result = mysqli_query($db,$query);
$array = array();
while($row = mysqli_fetch_assoc($result))
$array[] = $row;
foreach($array as $v)
$new_array[$v['name']][$v['action']] = $v['dt'];
print_r($new_array);
?>
输出:
Array
(
[Catherine] => Array
(
[in] => 2019-07-07 10:10:00
[lunch] => 2019-07-07 14:30:00
[out] => 2019-07-07 18:30:00
)
[John] => Array
(
[in] => 2019-07-07 10:00:00
[lunch] => 2019-07-07 13:00:00
[out] => 2019-07-07 18:00:00
)
[William] => Array
(
[in] => 2019-07-07 19:14:00
)
)
【讨论】:
select name,dob,city max(case when action = 'INTIME' then dateandtime end) as intime, max(case when action = 'OUTTIME' then dateandtime end) as outtime, max(case when action = 'LUNCH' then dateandtime end) as lunch from t group by name;我在此查询中还应用了其他列,但它不起作用 您在我的查询中看到任何聚合吗?不。在这种情况下,我无法理解您的评论的相关性。【参考方案3】:我使用了一个适合我的 CTE,如下
WITH cte
AS (SELECT Row_number()
OVER(
partition BY [name]
ORDER BY [name]) AS rn, *FROM table1)
SELECT a.[dateandtime] AS [IN],
b.[dateandtime] AS [OUT],
a.[action] AS [myaction],
c.[dateandtime] AS [lunchTIME]
FROM (SELECT *
FROM cte a
WHERE rn = 1) a
JOIN (SELECT *
FROM cte b
WHERE rn = 2) b
ON a.[name] = b.[name]
LEFT JOIN (SELECT *
FROM cte b
WHERE rn = 3) c
ON a.[name] = c.[name]
【讨论】:
以上是关于获取SQL表另一列对应的行记录的主要内容,如果未能解决你的问题,请参考以下文章
获取基于另一列的条件成立的每一行的最新记录(Hive SQL)