У меня есть запрос, который преобразует больше строки в одну строку. Я хотел знать, есть ли какая-либо техника лучше, чем. Чтобы проиллюстрировать наш случай, я применил простую связь с пользователями и смоделированные запросы, похожие на наше приложение.PostgreSQL - Объединение данных из нескольких строк в одну строку
table: Users PrimaryKey: UserId
---------------------------------------
| UserId | UserDetails1 | UserDetails2|
---------------------------------------
| 1 | name1 | Addr1 |
| 2 | name2 | Addr2 |
---------------------------------------
table: UserCars Unique Constraint(UserId, CarType)
index on userid, cartype
-------------------------------------------
| UserId | CarType | RedCount | BlueCount |
-------------------------------------------
| 1 | SUV | 1 | 0 |
| 1 | sedan | 1 | 2 |
| 2 | sedan | 1 | 0 |
-------------------------------------------
Consider CarType as an enum type with values SUV and sedan only
Применение должно принести UserDetails1, сумма (RedCount), сумма (BlueCount), RedCount внедорожник, BlueCount внедорожник, седан RedCount, седан BlueCount для каждого пользователя в одном запросе.
Для приведенного выше примера, результат должен быть как
--------------------------------------------------------------------------------
| UserId | UserDetails1 | TotalRed |TotalBlue|SUVRed|SUVBlue|sedanRed|sedanBlue|
--------------------------------------------------------------------------------
| 1 | name1 | 2 | 2 | 1 | 2 | 1 | 0 |
| 2 | name2 | 1 | 0 | 0 | 0 | 1 | 0 |
--------------------------------------------------------------------------------
В настоящее время наш запрос, как показано ниже
SELECT
--User Information
u.UserId, u.UserDetails1,
--Total Counts by color
count_by_colour.TotalRed, count_by_colour.TotalBlue,
-- Counts by type
COALESCE(suv.red, 0) AS SUVRed, COALESCE(suv.blue, 0) AS SUVBlue,
COALESCE(sedan.red, 0) AS sedanRed, COALESCE(sedan.blue, 0) AS sedanBlue
FROM Users u
JOIN (
SELECT c.UserId, SUM(RedCount) as TotalRed,
SUM(BlueCount) AS TotalBlue
FROM UserCars c GROUP BY UserId
) count_by_colour
ON (u.UserId = count_by_colour.UserId)
LEFT JOIN (
SELECT UserId, RedCount AS red, BlueCount AS blue
FROM UserCars
WHERE CarType = 'SUV') suv
ON (u.UserId = suv.UserId)
LEFT JOIN (
SELECT UserId, RedCount AS red, BlueCount AS blue
FROM UserCars
WHERE CarType = 'sedan') sedan
ON (u.UserId = sedan.UserId)
Хотя запрос извлекает данные, как и ожидалось, я хотел бы знать, если есть любой метод лучше этого. В этом примере я дал только два типа (внедорожник и седан), но в нашем оригинальном приложении, которое связано с маркетингом, есть больше типов, что означает больше левых объединений.
Примечание: таблицы не могут быть изменены, как есть и другие приложения используют один и тот же
Спасибо,
Ravi
Хотя этот запрос немного некрасиво, логически правильно, и я не могу придумать способ, чтобы упростить его. –
Вы уверены, что хотите как 'mysql', так и' postgresql'? –
@TimBiegeleisen Я немного изменил его и прокомментировал ниже.Он работает лучше, чем исходный запрос. –