sqlalchemy func.group_concat and random order of data

流过昼夜 提交于 2021-01-29 07:59:11

问题


I have a following query which is using func.group_concat to group some data

r  = aliased(Rank)
t  = aliased(Team)
p  = aliased(Participant)
players_ranks_data = (
    db.session.query(
        p,
        r.id.label('player_team_skill_id'),
        r.name.label('player_team_skill_name'),
        func.group_concat(t.name),
    )
    .outerjoin(r, r.id == p.team_skill)
    .outerjoin(t, t.id == p.team_id)
    .filter(p.event_id == event_data.id)
    .filter(p.team_id != '')
    .group_by('player_team_skill_name')
    .all()
)

When I'm printing what was retrieved

print('players_ranks_data: {}'.format(players_ranks_data))

I see full data, but doing this few times is giving me different order of returned data. For example: 1st execution

players_ranks_data: [(<Participant 104>, 4, u'advanced', u'text1,item1,other thingy,something else,what is that')]

2nd execution

players_ranks_data: [(<Participant 104>, 4, u'advanced', u'what is that, item1,other thingy, text1, something else')]

It's really weird because when I execute this query directly on DB (MySQL) I'm not always getting the same order of items in result too.

SELECT
  `Rank_1`.id AS player_team_skill_id,
  `Rank_1`.name AS player_team_skill_name,
  GROUP_CONCAT(`Team_1`.name) AS group_concat_1
FROM
  `Participant` AS `Participant_1`
  LEFT OUTER JOIN `Rank` AS `Rank_1`
    ON `Rank_1`.id = `Participant_1`.team_skill
  LEFT OUTER JOIN `Team` AS `Team_1`
    ON `Team_1`.id = `Participant_1`.team_id
WHERE `Participant_1`.event_id = 2
  AND `Participant_1`.team_id != ''
GROUP BY player_team_skill_name;

Is there anything missing in my original sqlalchemy query or in MySQL configuration?

EDIT 1: actually, I did some tests again and it seems that results in MySQL (5.7) are not ordered too. What's going on here?


回答1:


SQL results are (multi) sets and as such have no ordering, unless you explicitly define one. This applies to group rows produced by GROUP BY as well; there is no order within the groups, and so aggregates receive values in any which order the current query depending on plan, physical layout, scheduling etc. happens to produce. The solution is to explicitly define the order:

func.group_concat(t.name.op("ORDER BY")(t.name))

This uses a generic operator function to produce the required SQL syntax. SQLAlchemy provides the aggregate_order_by helper for the very same syntax, but it is provided for the Postgresql dialect only.



来源:https://stackoverflow.com/questions/58198288/sqlalchemy-func-group-concat-and-random-order-of-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!