save diferent outputs in array from select - postgresql

I have query with output where first 4 elements would be the same and the others different. I want to save these elements in array.
for example I have output:
where sid,name,time_from, time_to are the same values and id,type,count,from, to have different values.
I have query:
select asch.id as sid,
asch.name,
asch.time_from,
asch.time_to,
array_agg(ad.id) as ad_id,
array_agg(ad.type) as ad_type,
array_agg(ad.count)as ad_count,
array_agg(ad.from)as ad_from,array_agg(ad.to) as ad_to
from ad ad
join ad_ad_group aag on aag.ad_id=ad.id
join ad_group ag on ag.id=aag.ad_group_id
join ad_schedule asch on asch.ad_group_id=ag.id
join ad_shedule_device asd on asd.ad_schedules_id=asch.id
join device d on d.device_id=asd.devices_id
where d.device_id=4
group by asch.id
where depends on device_id Im selecting all ads on this device divide by ad shedule in which ad is located.
which output is:
but I want something like this:
Im really sorry for my bad English.

select asch.id as sid,
asch.name,
asch.time_from,
asch.time_to,
jsonb_agg(jsonb_build_object(
'ad_id'::text, ad.id,
'ad_type'::text, ad.type,
'ad_count'::text, ad.count,
'ad_from'::text, ad.from,
'ad_to'::text,ad.to
))
from ad ad
join ad_ad_group aag on aag.ad_id=ad.id
join ad_group ag on ag.id=aag.ad_group_id
join ad_schedule asch on asch.ad_group_id=ag.id
join ad_shedule_device asd on asd.ad_schedules_id=asch.id
join device d on d.device_id=asd.devices_id
where d.device_id=4
group by asch.id

Related

Is there a way to modify this query and make it more simple?

I am working on a MySQl data base and have several tables that I need to join based on a temporary table that I created (layer_2).
Each table that I join has the join key for the next table;
E.g. layer_2 joins with "colegios" table, then the result will have the join key for the next table "ciudades". and finally the result will have the Join key for the next table "departamentos".
from what I got it works but I want to know if there is a way to simplify this?
Select
cuestionario_id,
tiempo,
nro_preguntas,
nro_preguntas_correctas,
tipo_usuario,
fecha_creacion_cuestionario,
con_tiempo,
det_cuestionarios_id,
respuesta_seleccionada,
pregunta_id,
enunciado,
respuesta_correcta,
usuarios_id,
dominio_correo,
tipo_institucion,
materia,
tematica,
area,
nombre_colegios,
direccion_colegios,
nombre_ciudades,
redsaber.departamentos.nombre as nombre_departamentos
From
(
Select
cuestionario_id,
tiempo,
nro_preguntas,
nro_preguntas_correctas,
cuestionable_id,
tipo_usuario,
fecha_creacion_cuestionario,
con_tiempo,
det_cuestionarios_id,
respuesta_seleccionada,
pregunta_id,
enunciado,
respuesta_correcta,
usuarios_id,
dominio_correo,
cole_ciud_id,
tipo_institucion,
materia,
tematica,
area,
combine_ciudad_id,
nombre_colegios,
direccion_colegios,
redsaber.ciudades.nombre as nombre_ciudades,
departamento_id
From
(Select
cuestionario_id,
tiempo,
nro_preguntas,
nro_preguntas_correctas,
cuestionable_id,
tipo_usuario,
fecha_creacion_cuestionario,
con_tiempo,
det_cuestionarios_id,
respuesta_seleccionada,
pregunta_id,
enunciado,
respuesta_correcta,
usuarios_id,
dominio_correo,
cole_ciud_id,
tipo_institucion,
materia,
tematica,
area,
ifnull(redsaber.colegios.ciudad_id,cole_ciud_id) as combine_ciudad_id,
redsaber.colegios.nombre as nombre_colegios,
redsaber.colegios.direccion as direccion_colegios
From layer_2
Left Join redsaber.colegios on layer_2.cole_ciud_id = redsaber.colegios.id
AND tipo_institucion = 'Colegio') as layer_3
Left Join redsaber.ciudades on combine_ciudad_id = redsaber.ciudades.id) as layer_4
Left Join redsaber.departamentos on departamento_id = redsaber.departamentos.id

Postgresql, how to SELECT json object without duplicated rows

I'm trying to find out how to get JSON object results of selected rows, and not to show duplicated rows.
My current query:
SELECT DISTINCT ON (vp.id) jsonb_agg(jsonb_build_object('affiliate',a.*)) as affiliates, jsonb_agg(jsonb_build_object('vendor',vp.*)) as vendors FROM
affiliates a
INNER JOIN related_affiliates ra ON a.id = ra.affiliate_id
INNER JOIN related_vendors rv ON ra.product_id = rv.product_id
INNER JOIN vendor_partners vp ON rv.vendor_partner_id = vp.id
WHERE ra.product_id = 79 AND a.is_active = true
GROUP BY vp.id
The results that I receive from this is:
[
affiliates: {
affiliate: affiliate1
affiliate: affiliate2
},
vendors: {
vendor: vendor1,
vendor: vendor1,
}
As you can see in the second record, vendor is still vendor1 because there are no more results, so I'd like to also know if there's a way to remove duplicates.
Thanks.
First point : the result you display here above doesn't conform the json type : the keys are not double-quoted, the string values are not double-quoted, having dupplicated keys in the same json object ('{"affiliate": "affiliate1", "affiliate": "affiliate2"}' :: json) is not be accepted with the jsonb type (but it is with the json type).
Second point : you can try to add the DISTINCT key word directly in the jsonb_agg function :
jsonb_agg(DISTINCT jsonb_build_object('vendor',vp.*))
and remove the DISTINCT ON (vp.id) clause.
You can also add an ORDER BY clause directly in any aggregate function. For more information, see the manual.
You could aggregate first, then join on the results of the aggregates:
SELECT a.affiliates, v.vendors
FROM (
select af.id, jsonb_agg(jsonb_build_object('affiliate',af.*)) as affiliates
from affiliates af
group by af.id
) a
JOIN related_affiliates ra ON a.id = ra.affiliate_id
JOIN related_vendors rv ON ra.product_id = rv.product_id
JOIN (
select vp.id, jsonb_agg(jsonb_build_object('vendor',vp.*)) as vendors
from vendor_partners vp
group by vp.id
) v ON rv.vendor_partner_id = v.id
WHERE ra.product_id = 79
AND a.is_active = true

Why Group By is not working as expected in PostgreSQL?

I m doing a query and it is showing me the output but not as expected.
Above image it is giving me two extra row (blue indicator) after doing group by which not should be exists in the output. Here is my query
SELECT som.customer_po,
pro.product_id,
pro.product_name,
som.mo_id,
ri.status
FROM schema_order_map som
JOIN product pro ON som.label_reference_id = pro.product_id
JOIN risk_information ri ON som.customer_po = ri.customer_po
WHERE ri.created_by = 18
AND ri.product_id = som.label_reference_id
GROUP BY som.customer_po,
pro.product_id,
product_name,
som.mo_id,
ri.status
I tried different way but it is giving me the same result.
It solves my problem somehow. but i don't know it is best practice or not
SELECT max(som.customer_po) AS customer_po,
max(pro.product_id) AS product_id,
max(pro.product_name) product_name,
max(som.mo_id) mo_id,
max(ri.status) AS risk_status
FROM schema_order_map som
JOIN product pro ON som.label_reference_id = pro.product_id
JOIN risk_information ri ON som.customer_po = ri.customer_po
WHERE ri.created_by = 18
AND ri.product_id = som.label_reference_id
GROUP BY som.customer_po,
pro.product_id

Highlighting duplicate values

I have the following script:
SELECT
Reference.ReferenceNumber AS [Reference.ReferenceNumber)
Reference.LastName
Reference.FirstName
Address.ReferenceNumber AS [Address.ReferenceNumber]
Address.Address1
Address.Address2
Address.Address3
Address.Address4
Address.ZipCode
Telephone.ReferenceNumber AS [Telephone.ReferenceNumber]
Telephone.TelephoneNumber
Email.ReferenceNumber AS [Email.ReferenceNumber]
Email.EmailAddress
FROM
Reference
INNER JOIN Address
ON Reference.ReferenceNumber = Reference.ContactNumber
LEFT OUTER JOIN Telephone
ON Reference.ReferenceNumber = Telephone.ReferenceNumber
LEFT OUTER Join Email
ON Reference.ReferenceNumber = Email.ReferenceNumber
This pulls through all customers, plus their addresses, email and phone numbers.
However some have duplicate surnames and addresses.
Please can you advise an amendment to the script that would show which records were duplicates? Ideally I'd like the output to show where the surname, address 1 and the zipcode were identical and restrict the output to the duplicate rows only.
Many thanks.
something like
SELECT
Reference.ReferenceNumber AS [Reference.ReferenceNumber),
case when vrln.c is null then Reference.LastName else 'dup: ' + Reference.LastName end as LastName,
Reference.FirstName,
Address.ReferenceNumber AS [Address.ReferenceNumber],
Address.Address1,
Address.Address2,
Address.Address3,
Address.Address4,
Address.ZipCode,
Telephone.ReferenceNumber AS [Telephone.ReferenceNumber],
Telephone.TelephoneNumber,
Email.ReferenceNumber AS [Email.ReferenceNumber],
Email.EmailAddress
FROM
Reference
INNER JOIN Address
ON Reference.ReferenceNumber = Reference.ContactNumber
LEFT OUTER JOIN Telephone
ON Reference.ReferenceNumber = Telephone.ReferenceNumber
LEFT OUTER Join Email
ON Reference.ReferenceNumber = Email.ReferenceNumber
left join (
select rln.LastName, add.Address1, add.ZipCode, count(rln.LastName) as c
from
Reference rln
INNER JOIN Address add
ON rln.ReferenceNumber = add.ReferenceNumber
group by rln.LastName, add.Address1, add.ZipCode
having count(rln.LastName) > 1
) vrln on Reference.LastName = vrln.LastName and Address.Address1 = vrln.Address1 and Address.ZipCode = vrln.ZipCode
where vrln.c is not null
but, to find duplicates :
select rln.LastName, add.Address1, add.ZipCode, count(rln.LastName) as c
from
Reference rln
INNER JOIN Address add
ON rln.ReferenceNumber = add.ReferenceNumber
group by rln.LastName, add.Address1, add.ZipCode
having count(rln.LastName) > 1
is enough

Postgres Complex Select in a View

I have this select clause that is working perfect:
SELECT
"Aspectos"."ID" AS "Aspecto Normativo ID",
"Aspectos"."Aspecto" AS "Aspecto Normativo",
"Fatores"."ID", "Fatores"."Fator" AS "Fator Normativo",
"Diagnostico"."Vinculo_Final",
"Fatores_1"."ID",
"Fatores_1"."Fator" AS "Fator Determinativo",
"Aspectos_1"."ID" AS "Aspecto Determinativo ID",
"Aspectos_1"."Aspecto" AS "Aspecto Determinativo",
Count("Itens"."ID") AS "No Itens",
Count("Itens"."ID") AS "Pri"
FROM "Diagnostico" INNER JOIN ("Aspectos" AS "Aspectos_1"
INNER JOIN (("Fontes" INNER JOIN "Itens" ON "Fontes"."ID" = "Itens"."Fonte")
INNER JOIN ("Fatores" AS "Fatores_1"
INNER JOIN ("Aspectos"
INNER JOIN ("Vinculos"
INNER JOIN "Fatores"
ON "Vinculos"."Fator_Normativo" = "Fatores"."ID")
ON ("Aspectos"."ID" = "Fatores"."Aspecto")
AND ("Aspectos"."ID" = "Fatores"."Aspecto"))
ON "Fatores_1"."ID" = "Vinculos"."Fator_Determinativo")
ON "Itens"."ID" = "Vinculos"."Item")
ON "Aspectos_1"."ID" = "Fatores_1"."Aspecto")
ON "Diagnostico"."ID" = "Vinculos"."Diagnostico_ID"
GROUP BY "Aspectos"."ID", "Aspectos"."Aspecto",
"Fatores"."ID", "Fatores"."Fator",
"Diagnostico"."Vinculo_Final",
"Fatores_1"."ID",
"Fatores_1"."Fator",
"Aspectos_1"."ID",
"Aspectos_1"."Aspecto"
ORDER BY "Aspectos"."ID", "Aspectos_1"."ID",
"Fatores"."Fator", "Fatores_1"."Fator";
But when I try to CREATE A VIEW with this same select I'm getting thuis error:
ERROR: column "ID" specified more than one time
Can anybody help me on this.
Thanks
You have "Fatores"."ID" (line 4) and "Fatores_1"."ID" (line 6). Give them different aliases.
For such complex queries it is recommended to have only 1 (one) column in per line in the statement for better visibility. Also it is recommended to always give aliases to the columns.