问题
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