Поворот в MySQL - работает только на одной строке одновременно?
Я пытаюсь выбрать активы из базы данных RT со значениями для набора настраиваемых полей в виде таблиц. Соответствующие таблицы следующие:
mysql> describe AT_Assets;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| Type | int(11) | NO | MUL | 0 | |
| Name | varchar(200) | NO | MUL | NULL | |
| Description | varchar(255) | YES | | NULL | |
| Status | varchar(20) | YES | | NULL | |
| URI | varchar(255) | YES | | NULL | |
| LastUpdatedBy | int(11) | NO | | 0 | |
| LastUpdated | datetime | YES | | NULL | |
| Creator | int(11) | NO | | 0 | |
| Created | datetime | YES | | NULL | |
+---------------+--------------+------+-----+---------+----------------+
10 rows in set (0.00 sec)
mysql> describe CustomFields;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| Name | varchar(200) | YES | | NULL | |
| Type | varchar(200) | YES | | NULL | |
| RenderType | varchar(64) | YES | | NULL | |
| MaxValues | int(11) | YES | | NULL | |
| Pattern | text | YES | | NULL | |
| Repeated | smallint(6) | NO | | 0 | |
| BasedOn | int(11) | YES | | NULL | |
| ValuesClass | varchar(64) | YES | | NULL | |
| Description | varchar(255) | YES | | NULL | |
| SortOrder | int(11) | NO | | 0 | |
| LookupType | varchar(255) | NO | | NULL | |
| Creator | int(11) | NO | | 0 | |
| Created | datetime | YES | | NULL | |
| LastUpdatedBy | int(11) | NO | | 0 | |
| LastUpdated | datetime | YES | | NULL | |
| Disabled | smallint(6) | NO | | 0 | |
+---------------+-------------+------+-----+---------+----------------+
17 rows in set (0.00 sec)
mysql> describe ObjectCustomFieldValues;
+-----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| CustomField | int(11) | NO | MUL | NULL | |
| ObjectType | varchar(255) | NO | | NULL | |
| ObjectId | int(11) | NO | | NULL | |
| SortOrder | int(11) | NO | | 0 | |
| Content | varchar(255) | YES | MUL | NULL | |
| LargeContent | longblob | YES | | NULL | |
| ContentType | varchar(80) | YES | | NULL | |
| ContentEncoding | varchar(80) | YES | | NULL | |
| Creator | int(11) | NO | | 0 | |
| Created | datetime | YES | | NULL | |
| LastUpdatedBy | int(11) | NO | | 0 | |
| LastUpdated | datetime | YES | | NULL | |
| Disabled | smallint(6) | NO | | 0 | |
+-----------------+--------------+------+-----+---------+----------------+
Этот запрос успешно возвращает мне список всех активов, но повторяет ресурс в отдельном столбце для каждого значения настраиваемого поля:
SELECT AT_Assets.Name, AT_Assets.description, CustomFields.Name, ObjectCustomFieldValues.content FROM ObjectCustomFieldValues inner join CustomFields on ObjectCustomFieldValues.CustomField = CustomFields.id inner join AT_Assets on AT_Assets.id = ObjectCustomFieldValues.ObjectID order by AT_Assets.description;
Поэтому я немного почитал и научился вращаться. Теперь у меня есть это:
SELECT at_assets.name,
at_assets.description AS "Asset Tag",
Max(CASE
WHEN customfields.name = "make" THEN
objectcustomfieldvalues.content
END) AS "Make",
Max(CASE
WHEN customfields.name = "model" THEN
objectcustomfieldvalues.content
END) AS "Model",
Max(CASE
WHEN customfields.name = "primary user" THEN
objectcustomfieldvalues.content
END) AS "Primary User",
Max(CASE
WHEN customfields.name = "hostname" THEN
objectcustomfieldvalues.content
END) AS "Hostname",
Max(CASE
WHEN customfields.name = "os" THEN objectcustomfieldvalues.content
END) AS "OS",
Max(CASE
WHEN customfields.name = "purchase date (if known)" THEN
objectcustomfieldvalues.content
END) AS "Purchase Date"
FROM objectcustomfieldvalues
INNER JOIN customfields
ON objectcustomfieldvalues.customfield = customfields.id
INNER JOIN at_assets
ON at_assets.id = objectcustomfieldvalues.objectid
WHERE at_assets.id = 5
ORDER BY at_assets.description;
Что прекрасно работает, когда я указываю один актив. Тем не менее, я хотел бы, чтобы это работало на каждом активе В противном случае мне нужен скрипт Python, чтобы запускать это сотни раз вручную, увеличивая идентификатор ресурса, что довольно не элегантно. Как мне получить полный список?
2 ответа
Вы узнали все о сводке, кроме добавления group by
,
Добавьте следующую строку после where
:
group by at_assets.name, at_assets.description
Чтобы увидеть более одной строки, удалите или отрегулируйте where
пункт.
Что происходит с вашим запросом, так это то, что MySQL распознает его как запрос агрегации, потому что он использует MAX()
, Здесь нет group by
Таким образом, он производит одну строку - совокупность всех строк.
Как насчет переменных at_assets.name
а также at_assets.description
в select
статья? Вы можете спросить. Что ж, большинство движков SQL будут отказываться и выдавать ошибку. Эти переменные ни в group by
ни аргумент для функции агрегации. MySQL имеет (неправильную) функцию, называемую скрытыми столбцами, которая позволяет такие ссылки. Однако значения поступают из произвольных строк в исходных данных, поэтому значение не имеет смысла, если все значения в группе не совпадают.
Тебе просто нужно group by
Вот. и не указывайте имя актива.
изменить это
WHERE at_assets.id = 5
ORDER BY at_assets.description;
в
group by at_assets.name
ORDER BY at_assets.description;