2016-10-17 5 views
2

У меня странное поведение при использовании GROUP_CONCAT в подзапросе. Вот мой запрос:Weird result для GROUP_CONCAT в подзапросе

SELECT 
    name, 
    GROUP_CONCAT(DISTINCT (id) SEPARATOR "-") AS id 
FROM (
     (SELECT 
      "APN"           AS name, 
      GROUP_CONCAT(DISTINCT (site.id) SEPARATOR "-") AS id 
     FROM site 
     WHERE id IN 
       (138, 147, 8918, 8916, 9033, 9240, 97, 9038, 8886, 9036, 9067, 146, 37, 9127, 52, 9031, 23, 8635, 8665, 
       46, 39, 18, 33, 9035, 137, 9051, 8766, 25, 20, 9160, 133, 8636, 9021, 8655, 21, 42, 8757, 22, 9017, 77, 
       9037, 44, 49, 9323, 55, 74, 150, 8, 67, 1, 8928, 58, 9025, 9221, 9019, 9069, 9214, 9176, 95, 40, 9335, 
       168, 9260, 8641, 9227, 9258, 24, 50, 29, 9073, 12, 36, 8882, 9, 43, 76, 9032, 51, 9060, 96, 8922, 9212, 
       14, 9095, 28, 9213, 31, 41, 68, 9027, 8884, 9023, 9059, 9034, 9016, 11, 61, 9229, 8761, 9225, 8937, 9018, 
       9121, 9119, 8659, 8926, 9096, 57, 9083, 8662, 9232, 149, 8643, 88, 19, 8660, 10, 8936, 9210, 9241, 17, 8872)) 
     UNION ALL 
     (SELECT 
      "smart"          AS name, 
      GROUP_CONCAT(DISTINCT (site.id) SEPARATOR "-") AS id 
     FROM site 
     WHERE id IN 
       (9129, 8981, 9136, 9169, 9170, 9171, 9172, 9297, 9147, 9155, 9139, 9138, 9142, 9296, 8987, 9216, 9252, 
       9320, 8951, 8945, 8952, 8965, 8963, 9012, 9192, 8938, 8941, 8968, 8977, 9117, 9135, 9140, 9143, 9295, 
       9298, 9137, 8988, 8989, 8992, 9164, 9156, 9165, 9168, 9173, 8953, 8999, 8939, 8940, 8942, 8943, 8954, 
       8956, 8957, 8959, 8960, 8964, 8971, 8972, 8973, 8974, 8982, 9000, 9001, 9003, 8950, 8978, 8979, 8983, 
       9002, 9005, 8984, 8955, 8986, 8980, 8993, 9008, 9010, 8949, 8998, 9150, 9122, 8944, 8946, 8948, 9006, 
       9009, 9013, 9128, 9215, 9321, 9011, 9154, 8970, 8975, 8994, 9070, 8966, 8958, 9007, 9014)) 
    ) t 
GROUP BY name; 

(Это «тест» запрос легко показать вопрос, реальный вопрос не то, что «немой»). Он группирует результат из двух подзапросов. Все идентификаторы существуют и возвращают строку.

Итак, когда я запускаю первый подзапрос, я получаю результат «APN» для имени и «1-8-9-10-11-12-14-17-18-19-20-21-22 -23-24-25-28-29-31-33-36-37-39-40-41-42-43-44-46-49-50-51-52-55-57-58-61-67 -68-74-76-77-88-95-96-97-133-137-138-146-147-149-150-168-8635-8636-8641-8643-8655-8659-8660-8662-8665 -8757-8761-8766-8872-8882-8884-8886-8916-8918-8922-8926-8928-8936-8937-9016-9017-9018-9019-9021-9023-9025-9027-9031-9032-9033 -9034-9035-9036-9037-9038-9051-9059-9060-9067-9069-9073-9083-9095-9096-9119-9121-9127-9160-9176-9210-9212-9213-9214-9221-9225 -9227-9229-9232-9240-9241-9258-9260-9323-9335 "для ID (полный список идентификаторов)

То же самое для второго подзапроса, за исключением того, что имя« умное »и идентификаторы разные. Так что это ожидаемое поведение.

Проблема заключается в том, когда я запускаю полный запрос, для имени APN, я получаю следующий список идентификаторов: 1-8-9-10-11-12-14-17-18-19-20- 21-22-23-24-25-28-29-31-33-36-37-39-40-41-42-43-44-46-49-50-51-52-55-57-58- 61-67-68-74-76-77-88-95-96-97-133-137-138-146-147-149-150-168-8635-8636-8641-8643-8655-8659-8660- 8662-8665-8757-8761-8766-8872-8882-8884-8886-8916-8918-8922-8926-8928-8936-8937-9016-9017-9018-9019-9021-9023-9025-9027-9031- 9032-9033-9034

Так что этот список намного меньше первого. И это то же самое для названия «умный».

Я попытался заменить мои два подзапроса на (SELECT "APN" как имя, "1-8-9-10-11-12-14-17-etc ..." как id FROM site LIMIT 1) с помощью полный список идентификаторов (и то же самое для имени «умный»), и с этим результат полного запроса будет таким, как ожидалось (полный список идентификаторов для каждого имени).

group_concat_max_len 1024 на моем сервере (и мой полный список ID гораздо меньше, чем 1024 caracters)

Итак, у вас есть какие-либо идеи, почему результат не как ожидалось?

+0

Идея думать: некоторые из идентификаторов могут просто не существовать в вашей таблице в первую очередь –

+0

Я создал тестовую таблицу со всеми идентификаторами, и получаю тот же результат. Это озадачивает. – CGritton

+0

@Alma Do: Как я уже упоминал, все идентификаторы существуют и возвращают строку в таблице. (Если нет, они не будут возвращены, когда я запускаю только подзапросы) – user6050469

ответ

2

Ваш запрос немного странный.

select name, GROUP_CONCAT(DISTINCT(id) SEPARATOR "-") AS id FROM (
     (select "APN" AS name, GROUP_CONCAT(DISTINCT(site.id) SEPARATOR "-") AS id from site WHERE id IN (138,147,8918,8916,9033,9240,97,9038,8886,9036,9067,146,37,9127,52,9031,23,8635,8665,46,39,18,33,9035,137,9051,8766,25,20,9160,133,8636,9021,8655,21,42,8757,22,9017,77,9037,44,49,9323,55,74,150,8,67,1,8928,58,9025,9221,9019,9069,9214,9176,95,40,9335,168,9260,8641,9227,9258,24,50,29,9073,12,36,8882,9,43,76,9032,51,9060,96,8922,9212,14,9095,28,9213,31,41,68,9027,8884,9023,9059,9034,9016,11,61,9229,8761,9225,8937,9018,9121,9119,8659,8926,9096,57,9083,8662,9232,149,8643,88,19,8660,10,8936,9210,9241,17,8872)) 
    UNION ALL 
     (select "smart" AS name, GROUP_CONCAT(DISTINCT(site.id) SEPARATOR "-") AS id from site WHERE id IN (9129,8981,9136,9169,9170,9171,9172,9297,9147,9155,9139,9138,9142,9296,8987,9216,9252,9320,8951,8945,8952,8965,8963,9012,9192,8938,8941,8968,8977,9117,9135,9140,9143,9295,9298,9137,8988,8989,8992,9164,9156,9165,9168,9173,8953,8999,8939,8940,8942,8943,8954,8956,8957,8959,8960,8964,8971,8972,8973,8974,8982,9000,9001,9003,8950,8978,8979,8983,9002,9005,8984,8955,8986,8980,8993,9008,9010,8949,8998,9150,9122,8944,8946,8948,9006,9009,9013,9128,9215,9321,9011,9154,8970,8975,8994,9070,8966,8958,9007,9014)) 
) t GROUP BY name; 

равно:

(select "APN" AS name, GROUP_CONCAT(DISTINCT(site.id) SEPARATOR "-") AS id from site WHERE id IN (138,147,8918,8916,9033,9240,97,9038,8886,9036,9067,146,37,9127,52,9031,23,8635,8665,46,39,18,33,9035,137,9051,8766,25,20,9160,133,8636,9021,8655,21,42,8757,22,9017,77,9037,44,49,9323,55,74,150,8,67,1,8928,58,9025,9221,9019,9069,9214,9176,95,40,9335,168,9260,8641,9227,9258,24,50,29,9073,12,36,8882,9,43,76,9032,51,9060,96,8922,9212,14,9095,28,9213,31,41,68,9027,8884,9023,9059,9034,9016,11,61,9229,8761,9225,8937,9018,9121,9119,8659,8926,9096,57,9083,8662,9232,149,8643,88,19,8660,10,8936,9210,9241,17,8872)) 
    UNION ALL 
    (select "smart" AS name, GROUP_CONCAT(DISTINCT(site.id) SEPARATOR "-") AS id from site WHERE id IN (9129,8981,9136,9169,9170,9171,9172,9297,9147,9155,9139,9138,9142,9296,8987,9216,9252,9320,8951,8945,8952,8965,8963,9012,9192,8938,8941,8968,8977,9117,9135,9140,9143,9295,9298,9137,8988,8989,8992,9164,9156,9165,9168,9173,8953,8999,8939,8940,8942,8943,8954,8956,8957,8959,8960,8964,8971,8972,8973,8974,8982,9000,9001,9003,8950,8978,8979,8983,9002,9005,8984,8955,8986,8980,8993,9008,9010,8949,8998,9150,9122,8944,8946,8948,9006,9009,9013,9128,9215,9321,9011,9154,8970,8975,8994,9070,8966,8958,9007,9014)) 

Нет необходимости родительской группировки по имени и идентификатору, если исходный запрос не производит много строк APN с одной группой идентификаторов.

к вашему вопросу: Вы правы, что group_concat имеет максимальную длину 1024, но операция сортировки/объединения усекается далее до 1/3 (1024/3 = 341). (Хотя это известно, но не официальный документ не доступен для поддержки этого)

В вашем случае, просто увеличить группу CONCAT максимальное значение длины:

SET group_concat_max_len = 5000; 

и что должно дать нужный вам выход без усечения.

Вы можете создавать временные таблицы и объединять их, или вы можете вывести результат grou_concat в переменную. В обоих направлениях grop_concat будет усекать по его исходному значению по умолчанию.

+1

Это увлекательно. Я тоже заметил, что строки были ограничены 1024/3 = 341. Можете ли вы указать нам какую-либо документацию вообще об этом, даже что-то неофициальное, как сообщение в блоге? Мне это интересно. – CGritton

+0

Спасибо, это была именно эта проблема! Я попытался подойти к пределу и не нашел ничего. Для странного запроса я знаю, но, как я уже сказал, это был «тестовый» запрос, чтобы показать проблему, реальный запрос намного сложнее, и за этим стоит логика. В любом случае, спасибо, вы решили мою проблему! – user6050469