LINUX.ORG.RU

Сгруппировать в JSON данные

 


0

1

Использую СУБД PostgreSQL. Просьба помочь написать сложный запрос, есть таблица Users

User   UserDate
Петя   2024-01-01
Петя   2024-01-01
Петя   2026-01-01
Ваня   2025-01-02
Ваня   2025-01-02
Игорь  2025-06-10

В итоге нужен json вида

{
   Петя: {
       '2024-01-01': 2,
	   '2026-01-01': 1
   },
   Ввня: {
       '2025-01-02': 2
   },
   Игорь: {
	    '2025-06-10': 1
   }
} 

Моих знаний хватило только на такой запрос:

WITH tmp AS(
	SELECT
		COUNT(*) AS "kolvo",
		"UserData"
		"User"

	FROM  "Users"
	GROUP BY "User",  "UserData"
),
tmp1 AS(
	SELECT 
		"User",
		array_agg(
			json_build_object(
				"UserDate"::text, "kolvo"
			)
		) AS "user_json"
	GROUP BY "User"
)	

SELECT 
	array_agg(
		json_build_object(
			"User", "user_json"
		)
	)
FROM tmp1

Тут в итоге получается массив json, внутри тоже массив из json. Нужно просто json значения которого тоже json



Последнее исправление: polin11 (всего исправлений: 2)
Ответ на: комментарий от no-such-file

Спрашиваю у всех, а не только у гопоты, школоты и т.д.

В результате нужно получить json вида: ключ - User, значение - json (ключ UserDate, значение - кол-во вхождений UserDate у конкретного User)

Набор данных:

User   UserDate
Петя   2024-01-01
Петя   2024-01-01
Петя   2026-01-01
Ваня   2025-01-02
Ваня   2025-01-02
Игорь  2025-06-10

Результат:

{
   Петя: {
       '2024-01-01': 2,
       '2026-01-01': 1
   },
   Ввня: {
       '2025-01-02': 2
   },
   Игорь: {
       '2025-06-10': 1
   }
} 
polin11
() автор топика
Последнее исправление: polin11 (всего исправлений: 1)

в таком виде это по-моему нельзя сделать - в pg нет функций для конструирования json с именованными ключами и значениями json.

https://postgrespro.ru/docs/postgresql/17/functions-json

максимум чего-нить такое:

core=> select * from users ;
 kuser |  userdate
-------+------------
 петя  | 2024-01-01
 петя  | 2024-02-01
 петя  | 2024-02-01
 вася  | 2024-02-01
 вася  | 2024-02-01
 гога  | 2024-02-01

core=> select json_object(array_agg(s2.u)::text[], array_agg(s2.k)::text[]) from (
  select s1.kuser as u, json_object(array_agg(s1.userdate)::text[], array_agg(s1.kolvo)::text[]) k  from (
        SELECT COUNT(*) AS "kolvo", "userdate", "kuser" FROM  "users" GROUP BY "kuser",  "userdate"
  ) s1
  group by s1.kuser
  ) s2;
                                                               json_object
-----------------------------------------------------------------------------------------------------------------------------------------
 {"гога" : "{\"2024-02-01\" : \"1\"}", "петя" : "{\"2024-02-01\" : \"2\", \"2024-01-01\" : \"1\"}", "вася" : "{\"2024-02-01\" : \"2\"}"}


в любом языке программирования это делается 3 минуты зачем изгаляться на чистом pg?

vtVitus ★★★★★
()
Ответ на: комментарий от polin11

SQL не знаю, но погуглив

jsonb_object_agg(имя, значение)	(any, any)	jsonb	Нет	агрегирует пары имя/значение в виде объекта JSON (NULL допускается в значениях, но не в именах)

Хочешь объект оформляй как объект, а не как массив. Кажется оно

LINUX-ORG-RU ★★★★★
()
WITH cte_dat("User", "UserDate") AS (
	VALUES
		('Петя', '2024-01-01'),
		('Петя', '2024-01-01'),
		('Петя', '2026-01-01'),
		('Ваня', '2025-01-02'),
		('Ваня', '2025-01-02'),
		('Игорь', '2025-06-10')
)
SELECT 
	json_object_agg(y."User", y.dg)
FROM (
	SELECT
		 x."User"
		,json_object_agg(x."UserDate", x.cnt) AS dg
	FROM (
		SELECT 
			 cd."User"
			,cd."UserDate"
			,count(*) AS cnt
		FROM
			cte_dat cd
		GROUP BY
			1,2
	) x
	GROUP BY 1
) y
;
Toxo2 ★★★★
()
Ответ на: комментарий от polin11

В настоящее время сленг «гопота» на профильных ИТ-ресурсах означает ChatGPT и прочие ИИшенки. Если сможете правильно сформулировать задачу - оно вам даже рабочий код напишет =)

ALiEN175
()
Последнее исправление: ALiEN175 (всего исправлений: 1)
Ответ на: комментарий от polin11

Спрашиваю у всех, а не только у гопоты, школоты и т.д.

Т.е. настолько всё плохо? Мальчик, тебе не надо в ИТ. Я понимаю, что ты можешь чего-то не знать. Но как минимум из спортивного интереса можно же было погуглить что такое вайб кодинг? Как ты собрался в очистке работать, а?

no-such-file ★★★★★
()
Ответ на: комментарий от ALiEN175

Если сможете правильно сформулировать задачу

то в любом поисковике 1-2 ссылка будет ответом, гопота сама ничего не умеет, она перерабатывает готовые решения из поисковиков в попытках найти наиболее подходящее под запрос.

Kolins ★★★★★
()
Ответ на: комментарий от cobold

И в чем проблема?

JSON-текст представляет собой (в закодированном виде) одну из двух структур:

Набор пар ключ: значение. В различных языках это реализовано как запись, структура, словарь, хеш-таблица, список с ключом или ассоциативный массив. Ключом может быть только строка, значением — любая форма.

anonymous
()
Ответ на: комментарий от cobold

Я бы согласился с тем что с такими ключами могут быть проблемы с описанием схемы и валидацией но в JSON schema завезли матчинг наименований свойств https://www.learnjsonschema.com/2020-12/applicator/propertynames/ https://www.learnjsonschema.com/2020-12/applicator/patternproperties/ и в том же JSON schema используются «неправильные» служебные ключи с префиксом «$» да и сам JS ничего не имеет против объектов вида {«foo bar baz»: 12345}.

anonymous
()
Ответ на: комментарий от cobold

И что кардинально изменится (кроме исчезновения возможности быстро проверить наличие определенного ключа в наборе данных/обновлению/выборки по этому ключу) если вместо {«foo bar»: 1, «bar baz»: 2} использовать [[«foo bar», 1], [«bar baz», 2]]? Может еще запретить использовать UUID и прочие составные идентификаторы для ключа во всяких kv хранилищах?

anonymous
()
Ответ на: комментарий от Kolins

Ты пробовал гопотой пользоваться? Даже если влом с телефоном из США мутить и бабки туда впихивать, то возьми хоть https://mistral.ai/ хоть deep seek и посмотри сам, как оно работает. С тупой задачей ТС-а оно справится.

peregrine ★★★★★
()
Ответ на: комментарий от peregrine

Ты пробовал гопотой пользоваться?

Гопотой нет, пробовал болванчика от сбера. Если правильно сформировать вопрос то и в поисковике найти можно, а генерировать код, в котором ты еще и не смыслишь ну это стрелять в ногу, хрен знает что оно там напишет.

Kolins ★★★★★
()
Ответ на: комментарий от Kolins

стрелять в ногу

https://ixbt.games/news/2025/03/12/entuziast-poteryal-2-tysyaci-dollarov-na-t...

«Я ничего не понимаю в программировании, в кодинге, в устройстве игр, я просто хотел смешной перевод для Dark Souls 3!
Я пошел в чат GPT и спросил его: «как мне сделать такой мод?» Чат GPT написал мне приложение, помог с настройкой Google Translate API, но приложение которое он сделал было настолько кривым, что оно сделало 8 миллионов запросов в API гугла за ночь. Через неделю мне пришел счет от гугл, общая сумма задолжности перед ними у меня была 1746$ (с учетом выделенных средств при использовании API, получается, что траты на мод составили более 2000$)

Kolins ★★★★★
()