mysql同一个表中如何根据不同的条件将查询到的记录放到一个结果集中

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql同一个表中如何根据不同的条件将查询到的记录放到一个结果集中相关的知识,希望对你有一定的参考价值。

现有表如下:
id time is_login
3 2012-07-03 11:20:20 1
3 2012-07-03 11:25:20 0
3 2012-07-03 12:30:20 1
3 2012-07-03 12:20:50 0

is_login值等于1表示登录,等于0表示登出,那么如何通过一条sql语句查询出登录时间和登出时间呢?

参考技术A sql server的做法是:
select * from table where is_login=1
union
select * from table where is_login=0
mysql也有union,应该也可以正常使用。你试试 。

如果是查询最后一次登录时间和登出时间,条件中加上时间条件就OK了。希望能对你有帮助。追问

我需要的是这样显示:
id login_ time logout_time
3 2012-07-03 11:20:20 2012-07-03 11:25:20
3 2012-07-03 12:20:20 2012-07-03 12:30:50

追答

你数据表里面有字段能区分,比如你问题补充里面,四条时间。哪两条是一对吗?如果不能,实现很麻烦

追问

没有字段区分啊,麻烦也要做啊,你有什么好的方法呢?也许你也曾经做过类似的需求吧,不妨我们来一起探讨一下啊!

追答

为什么不考虑改下表结构呢?你这样的表结构无法确认哪条登陆对应那条登出。虽然说可以从最近的两个时间点来取。但是如果哪条登出信息丢失了,那就会出问题了啊。

你这个表的结构只有这三个字段吗?如果不是,把其他字段列出来看看

追问

t_log_login | CREATE TABLE `t_log_login` (
`ID` bigint(20) NOT NULL AUTO_INCREMENT,
`ROLE_ID` int(11) NOT NULL,
`LOGIN_TIME` datetime NOT NULL,
`IS_LOGIN_IN` tinyint(3) unsigned NOT NULL,
`IP` varchar(50) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `ROLE_ID` (`ROLE_ID`,`LOGIN_TIME`),
KEY `ROLE_ID_2` (`ROLE_ID`,`IP`)
ENGINE=MyISAM AUTO_INCREMENT=204 DEFAULT CHARSET=gbk |

参考技术B 从你给的数据就看得出你做事很粗心。
------------
id time is_login
3 2012-07-03 11:20:20 1
3 2012-07-03 11:25:20 0
3 2012-07-03 12:30:20 1 登录时间晚于登出时间?
3 2012-07-03 12:20:50 0
-------------
然后你的预期又是
id login_ time logout_time
3 2012-07-03 11:20:20 2012-07-03 11:25:20
3 2012-07-03 12:20:20 2012-07-03 12:30:50
--------------
这种设计的确有问题,最好一个令牌一次登录和登出。这样简便的多。
假设你给的数据是一一对应的,可以没有登出。
那么如下排序比对的方式:

USE TEST;
SELECT
M.ID,M.Time as login_time,N.Time as logout_time
FROM
(
SELECT A.ID,A.Time,@k:=@k+1 AS rank
FROM
(
SELECT ID,Time FROM loginlog where is_login=1 ORDER BY Time ASC
) A ,(SELECT @k:=0) B
) M
LEFT JOIN
(
SELECT A.ID,A.Time,@r:=@r+1 AS rank
FROM
(
SELECT ID,Time FROM loginlog where is_login=0 ORDER BY Time ASC
) A ,(SELECT @r:=0) B
) N on(M.ID=N.ID and M.rank=N.rank)

----------
执行结果:
id login_ time logout_time

'3' '2012-07-03 11:20:20' '2012-07-03 11:25:20'
'3' '2012-07-03 12:20:20' '2012-07-03 12:30:50'追问

老大,首先谢谢你指出我的缺点,我虚心接受,并谢谢你百忙之中回答了我的问题。
按照你的代码我进行了测试,可是为什么取出的登出时间的记录不完整呢??

追答

很简单。故事往往有个开头,而没有结尾。

也就是正在登录的ID是有可能的。

SELECT id, 。。。。FROM 表名 GROUP BY id
像这种查询 必然不会考虑到这种情况。

参考技术C

参考技术D select * from 表名 where id=3 and (is_login=1 or is_login=0)追问

我需要的是这样显示:
id login_ time logout_time
3 2012-07-03 11:20:20 2012-07-03 11:25:20
3 2012-07-03 12:20:20 2012-07-03 12:30:50
有没有好的办法??多谢了,在线等待好消息!

追答

SELECT id, MAX(CASE is_login WHEN '1' THEN time END) AS login_time,
MAX(CASE is_login WHEN '0' THEN time END) AS login_out
FROM 表名 GROUP BY id

这一条SQL语句花费了我一下午时间,太难了,得分真不容易啊!

追问

感动之极,无以为谢,分虽不多,但请笑纳。
另外顺便再问一个问题,假如登录时间和登出时间不对应,如连续两次(或以上)登录或登出,怎么去除重复的登录和登出,从而保证数据的准确性呢?

追答

不太清楚你的问题。举例说一下。是一个ID在一天之内连续登录或登出,还是一个ID所有的登录和登出时间?说详细一点。

本回答被提问者采纳

如何根据另一列的条件查询同一列两次?

【中文标题】如何根据另一列的条件查询同一列两次?【英文标题】:How to query the same column twice based on conditions of another column? 【发布时间】:2017-04-05 16:49:54 【问题描述】:

我是 TSQL 的初学者,希望获得一些关于 TSQL 条件的指导

有没有办法将同一个 SQL 字段作为不同的列进行查询?当文件从我们定义的不同状态移动时,我的字段名称会发生​​变化,我正在尝试使用状态变化中的相关时间戳来分析一些趋势。例如,文件的关联数据如下所示:

<File_History
Loanstatusdescriptor= “Underwrite Assigned” Status.EventTime= “4/1/2017 12:05”>

<File_History
        Loanstatusdescriptor= “Closing Request Received” Status.EventTime= “4/3/2017 17:15”>

我正在创建一份报告,该报告基于某些文件在工作流程中移动时的状态。 查询是否类似于:

SELECT

LoanInfo.UnderwriterName

,File_History.Status.EventTime (IF loanstatusdescriptor= “Underwrite Assigned”) AS ‘Underwriter Assigned Date’

,File_History.Status.EventTime ( IF loanstatusdescriptor= “Closing Request Received”) AS ‘Closing Request Receieved Date’

….

最终产品看起来像

    Underwriter|Underwriter Assigned Date |Closing Request Received Date  
    Bobby Brown    4/1/2017                 4/3/2017
    Sally Jones    4/7/2017                 4/9/2017
    Chris Graff    4/6/2017                 4/17/2017

如何写出允许根据贷款状态创建列的 T-SQL 语句?

【问题讨论】:

你能告诉我们你的表架构吗? 【参考方案1】:

假设File_History_Status 是一个可以连接到LoanInfo 的表:

对已知数量的列使用条件聚合:

select 
    li.UnderwriterName
  , [Underwriter_Assigned_Date] = max(case 
      when fhs.LoanStatusDescriptor = 'Underwriter Assigned' 
        then fhs.EventTime 
      end)
  , [Closing_Request_Received_Date] = max(case 
      when fhs.LoanStatusDescriptor = 'Closing Request Received' 
        then fhs.EventTime 
      end)
from LoanInfo li
  inner join File_History_Status fhs
    on li.LoanId = fhs.LoanId
group by li.UnderwriterName

【讨论】:

您好 SqlZim,感谢您的回复。将其他一些表加入查询时,聚合 MAX 会阻止其他列包含在查询中。删除聚合函数允许查询运行,但在用户定义的列中创建了多个重复的 Null。我应该将所有这些列添加到查询的 GROUP BY 部分以允许查询运行吗? @J.Mora 是的,您将在group by 中包含所有未聚合的列。 非常感谢您的帮助! @J.Mora 乐于助人!

以上是关于mysql同一个表中如何根据不同的条件将查询到的记录放到一个结果集中的主要内容,如果未能解决你的问题,请参考以下文章

MySQL根据条件查询表名,并提取这些表的数据。

MYSQL如何将查询到的数据全部显示出来的实例

MYSQL 如何把查询到的结果插入到另一个表中?

MYSQL如何将或许到的数据作为查询条件

mysql中sql语句查询的同时根据条件将数据插入到另一个表的做法?

mysql 如何把查询到的结果插入到另一个表中