Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python SQL:如何将两列分组为无序对?_Python_Mysql_Sql_Sqlalchemy - Fatal编程技术网

Python SQL:如何将两列分组为无序对?

Python SQL:如何将两列分组为无序对?,python,mysql,sql,sqlalchemy,Python,Mysql,Sql,Sqlalchemy,我正在用MySQL实现一个聊天系统,使用SQLAlchemy作为我的ORM。 我的表格有以下列:id、from\u user\u id、to\u user\u id、message、time\u sent. 我正在尝试创建一个查询,在该查询中,我选择包含每个对话发送的最新消息的记录。这与人们在Facebook上看到的对话列表一模一样 有什么办法吗? 以下是我到目前为止的情况: latest_msg_sq = (DBSession.query(func.max(Message.id).label(

我正在用MySQL实现一个聊天系统,使用SQLAlchemy作为我的ORM。
我的表格有以下列:
id、from\u user\u id、to\u user\u id、message、time\u sent.

我正在尝试创建一个查询,在该查询中,我选择包含每个对话发送的最新消息的记录。这与人们在Facebook上看到的对话列表一模一样
有什么办法吗?
以下是我到目前为止的情况:

latest_msg_sq = (DBSession.query(func.max(Message.id).label("max_id"))
.group_by(Message.from_user)).subquery()    
matching_conv = DBSession.query(Message)
.join(latest_msg_sq, and_(Message.id ==  
latest_msg_sq.c.max_id)).order_by(Message.time_sent.desc()) 

不幸的是,它工作得不是很好,因为它只获取了FasuxUsRyId的最新消息。我需要它也考虑来自TouUsSeriID的消息,而GypPyBy似乎不是最好的方法。在我看来,我认为我需要考虑从UsUrSyID和ToUsUrthIID作为无序对的记录,然后在这些对上使用GROPYBY。但是,我不知道怎么做。

在MySQL中,您将使用
least()
grest()
。要获取最近的时间,请执行以下操作:

select least(from_user_id, to_user_id) as u1, greatest(from_user_id, to_user_id) as u2,
       max(time_sent) as maxts
from messages
group by least(from_user_id, to_user_id), greatest(from_user_id, to_user_id)
要获取完整消息,您可以将其重新加入:

select m.*
from (select least(from_user_id, to_user_id) as u1, greatest(from_user_id, to_user_id) as u2,
             max(time_sent) as maxts
      from messages
      group by least(from_user_id, to_user_id), greatest(from_user_id, to_user_id)
     ) m2 join
     messages m
     on least(m2.from_user_id, m2.to_user_id) = least(m.from_user_id, m.to_user_id) and
        greatest(m2.from_user_id, m2.to_user_id) = greatest(m.from_user_id, m.to_user_id)
我不确定你会如何在SQLalchemy中表达这一点。

试试这个:

select msg1.* from message msg1
left outer join message msg2 on 
(msg1.from_user_id = msg2.from_user_id 
and msg1.to_user_id = msg2.to_user_id and msg2.time_sent > msg1.time_sent)
left outer join message msg3 on 
msg1.to_user_id = msg3.from_user_id 
and msg1.from_user_id= msg3.to_user_id and msg3.time_sent > msg1.time_sent
where msg2.id is null and msg3.id is null

SQLAlchemy版Mohsen Heydari的答案适用于任何需要它的人:

msg1 = aliased(Message)
msg2 = aliased(Message)
msg3 = aliased(Message)
matching_conv = DBSession.query(msg1)
matching_conv = matching_conv.outerjoin(msg2, and_(msg1.from_user==msg2.from_user, msg1.to_user==msg2.to_user, msg2.id > msg1.id))
matching_conv = matching_conv.outerjoin(msg3, and_(msg1.to_user==msg3.from_user, msg1.from_user==msg3.to_user, msg3.id > msg1.id))
matching_conv = matching_conv.filter(and_(msg2.id == None, msg3.id == None)).order_by(msg1.time_sent.desc())

关于如何在SQLAlchemy中实现这一点,有什么想法吗?它们是简单的左连接。我不熟悉SQLAlchemy,但任何支持左joinsChat的ORM应用程序通常都有一个房间抽象,它使用自己的唯一id实现。与其尝试将
从用户id加上
到用户id
转换为对话,如果您的
messages
表中有以下列可能会更好:
id、所有者、房间、消息、发送时间
,因此您可以选择按
房间
和按
发送时间
排序。