BigQuery SQL : Dynamically Concat all rows in column by key - sql

I have a table like this:
Customer Plan/Date
A free (20/01/2020-01/02/2020)
A starter (01/02/2020-01/03/2020)
A full (01/03/2020)
B trial (02/03/2020-05/04/2020)
B full (05/04/2020)
.....
.....
I need concat strings in column Plan/Date by Customer Key
And Get Output like this:
Customer Plans
A free (20/01/2020-01/02/2020), starter (01/02/2020-01/03/2020), full (01/03/2020)
B trial (02/03/2020-05/04/2020), full (05/04/2020)
The main challenge is that the number of rows for each customer can be different
Thanks for the help :)

If you want a string, then you want string_agg():
select customer,
string_agg(plans, ', ')
from t
group by customer;

Consider below - I think it is important to keep proper order in final list
select Customer,
string_agg(Plan_Date, ', ' order by parse_date('%d/%m/%Y', regexp_extract(Plan_Date, r'\((.{10})'))) as Plans
from `project.dataset.table`
group by Customer

Related

SQL - Returning fields based on where clause then joining same table to return max value?

I have a table named Ticket Numbers, which (for this example) contain the columns:
Ticket_Number
Assigned_Group
Assigned_Group_Sequence_No
Reported_Date
Each ticket number could contain 4 rows, depending on how many times the ticket changed assigned groups. Some of these rows could contain an assigned group of "Desktop Support," but some may not. Here is an example:
Example of raw data
What I am trying to accomplish is to get the an output that contains any ticket numbers that contain 'Desktop Support', but also the assigned group of the max sequence number. Here is what I am trying to accomplish with SQL:
Queried Data
I'm trying to use SQL with the following query but have no clue what I'm doing wrong:
select ih.incident_number,ih.assigned_group, incident_history2.maxseq, incident_history2.assigned_group
from incident_history_public as ih
left join
(
select max(assigned_group_seq_no) maxseq, incident_number, assigned_group
from incident_history_public
group by incident_number, assigned_group
) incident_history2
on ih.incident_number = incident_history2.incident_number
and ih.assigned_group_seq_no = incident_history2.maxseq
where ih.ASSIGNED_GROUP LIKE '%DS%'
Does anyone know what I am doing wrong?
You might want to create a proper alias for incident_history. e.g.
from incident_history as incident_history1
and
on incident_history1.ticket_number = incident_history2.ticket_number
and incident_history1.assigned_group_seq_no = incident_history2.maxseq
In my humble opinion a first error could be that I don't see any column named "incident_history2.assigned_group".
I would try to use common table expression, to get only ticket number that contains "Desktop_support":
WITH desktop as (
SELECT distinct Ticket_Number
FROM incident_history
WHERE Assigned_Group = "Desktop Support"
),
Than an Inner Join of the result with your inner table to get ticket number and maxSeq, so in a second moment you can get also the "MAXGroup":
WITH tmp AS (
SELECT i2.Ticket_Number, i2.maxseq
FROM desktop D inner join
(SELECT Ticket_number, max(assigned_group_seq_no) as maxseq
FROM incident_history
GROUP BY ticket_number) as i2
ON D.Ticket_Number = i2.Ticket_Number
)
SELECT i.Ticket_Number, i.Assigned_Group as MAX_Group, T.maxseq, i.Reported_Date
FROM tmp T inner join incident_history i
ON T.Ticket_Number = i.Ticket_Number and i.assigned_group_seq_no = T.maxseq
I think there are several different method to resolve this question, but I really hope it's helpful for you!
For more information about Common Table Expression: https://www.essentialsql.com/introduction-common-table-expressions-ctes/

How to store output using different unique key (tried CROSS APPLY STRING_SPLIT)?

I'm trying to understand how I can convert what is currently stored in my sql tbl. The LBid is the unique ID and the productString column contains all of the product IDs that exist within each LBid. I need to write a statement to store each individual product ID (stored within productString) as the unique ID with all the associated LBids in a CSV format.
Current output
LBid title noProducts productString
51631 Slide2 NULL NULL
51636 Slide3 1 49518
51638 Slide4 1 49512
51641 Slide5 2 49512,49518
51643 Slide6 4 49512,46163,49518,46157
51645 Slide7 3 49874,47339,46165
51647 Slide8 5 49874,48807,49934,46766,47339
51649 Slide9 7 46165,48807,49874,47339,46766,47648,47948
Desired output
Product ID LBid
49518 51636,51641,51643
49512 51638,51641,51643
etc...
I've tried using the following code which helps me to split out the productString column, but I don't know how to save the output from this SELECT statemnet.
SELECT value, LBid, title, noProducts, productString
FROM dbo.LB
CROSS APPLY STRING_SPLIT(productString, ',')
GROUP BY value, LBid, title, noProducts, productString
ORDER BY value;
Output from above statement (this is a sample, may not directly reflect above code)
value id title productString
45891 52316 Slide337 45891,47205,47205,47209,47209,47443,47447,49246,47131,48744,48746
45909 52708 Slide533 47260,47248,49204,50783,48817,47270
45911 52708 Slide533 47260,47248
45917 51893 Slide129 45917,47910,46073,46077,50119,48813,45921,46729,46708,46706
45921 51893 Slide129 45917,47910,46073,46077,50119,48813,45921,46729,46708,46706
45923 51843 Slide104 50299,50132,50130,49548,49496,49577,45923,50060,46706
45923 51845 Slide105 45923,49577,50132,48923,46706,49747
Any help would be greatly appreciated.
Thanks
SQL Azure / SMSS
I need to write a statement to store each individual product ID (stored within productString) as the unique ID with all the associated LBids in a CSV format.
You need to aggregate:
SELECT lb.LBid, STRING_AGG(s.value, ',')
FROM dbo.LB CROSS APPLY
STRING_SPLIT(lb.productString, ',') s
GROUP BY lb.LBid
ORDER BY lb.LBid;

multiplie outputs with different wheres

What do I have to change to get different results from different names.The table should give me the debts of each of them, this is calculated by the amount and the price of the drink. Now it should show all the names with the corresponding invoice that happens after the select
%sql select name, sum(getraenk.preis*schulden.menge) schulden from schulden \
join person on (fk_person = person.id)\
join getraenk on (fk_getraenk = getraenk.id)\
where name like ("dani")
Edit: it should spend all the names with their debts, that is:
dani = 8.5
michael = 12.5
...
Just in case your problem is very simple, you should be able to see all names and values with an SQL that looks like this:
select name, getraenk.preis*schulden.menge schulden
from schulden
join person on (fk_person = person.id)
join getraenk on (fk_getraenk = getraenk.id)
Note that I removed the where clause... this was the part that limited it to one name.
You also don't need the sum clause here unless you are doing a group by
Have you considered simply using GROUP BY name at the end of this query?
https://www.w3schools.com/sql/sql_groupby.asp
This will give you the sum of total debt for all names in your table which sounds like the result you are looking for.
You're missing
GROUP BY name
in the query.

Extract values from repeated columns in an array with BigQuery

Each array consists of information about which list (internal_list_id) does a certain contact belong to (vid).
I'm trying to include all internal_list_id (separated by comma) in one column grouped by vid.
The end data should like something like:
ContactID | ListMembership:
3291601 1058,1060
I've tried with the below code but it returns information about the first object only:
SELECT list_memberships[offset(1)].vid ContactId, list_memberships[offset(1)].internal_list_id ListMembership FROM hs.contacts as c
The below results is achieved via:
SELECT list_memberships FROM hs.contacts as c
P.S. If you have any suggestions for better a title please let me know. Thanks!
Use STRING_AGG(x) FROM UNNEST(array), like in:
WITH data AS (
SELECT visitStartTime, hits[OFFSET(0)].product
FROM `bigquery-public-data.google_analytics_sample.ga_sessions_20170801`
LIMIT 100
)
SELECT visitStartTime, (
SELECT STRING_AGG(FORMAT('$%i', localProductPrice), ', ')
FROM UNNEST(product)
) aggregated
FROM data

How to use SELECT DISTINCT and CONCAT in the same SQL statement

So I am feeding the results of this SQL into an array. The array later becomes the suggestions for a textbox that operates while typing. I want it to only return each name 1 time, even if the person has multiple appointments. Currently, this returns all appointments for the person with that name, so if "Brad Robins" has 5 appointments, and I start to type "Brad", it displays "Brad Robins" 5 times in the suggestions instead of only once.
$sql = "SELECT DISTINCT CONCAT(clients.studentFirstName, ' ', clients.studentLastName) AS name, appointments.location, appointments.subLocation, appointments.appointmentAddress1, appointments.appointmentAddress2, appointments.appointmentCity, appointments.appointmentState, appointments.appointmentZip, appointments.startTime, appointments.endTime, appointments.date, clients.school
FROM appointments JOIN clients
ON appointments.clientID = clients.clientID
WHERE CONCAT(clients.studentFirstName, ' ', clients.studentLastName) = '".$roommate."' AND clients.school = '".$school."';";
To me, it just seems like DISTINCT and CONCAT aren't playing nicely together.
The problem are the other fields; DISTINCT applies to the whole result. Probably the best thing is to do to separate queries or populate 2 different arrays; if you ORDER BY name, you can remove duplicates by copying into the dest array only when the name changes.
Don't use DISTINCT, use group by:
$sql = "SELECT CONCAT(clients.studentFirstName, ' ', clients.studentLastName) AS name, appointments.location, appointments.subLocation, appointments.appointmentAddress1, appointments.appointmentAddress2, appointments.appointmentCity, appointments.appointmentState, appointments.appointmentZip, appointments.startTime, appointments.endTime, appointments.date, clients.school
FROM appointments JOIN clients
ON appointments.clientID = clients.clientID
WHERE CONCAT(clients.studentFirstName, ' ', clients.studentLastName) = '".$roommate."' AND clients.school = '".$school."' group by CONCAT(clients.studentFirstName, ' ', clients.studentLastName);";
Also be careful about XSS in $school and $roomate if this accessible outside.
Distinct goes against the entire row of ALL columns, not just the name portion... So if the appointments are on different date/times, locations, etc, they will all come out. If all you want to show is the NAME portion, strip the rest of the other content. Query the available appointments AFTER a person has been chosen.
You could use
group by name
at the end, which would cause the query to return only one of each name, but then you can't predict what appointment results will be returned in cases where a client has multiple appointments, and the query stops being very useful.
Like others have pointed out, you should probably just get the list of appointments after the client has been chosen.
select colA||' - '||colB
from table1
where colA like 'beer%'
group by colA||' - '||colB
order by colA||' - '||colB
;
SELECT DISTINCT MD5(CONCAT(clients.studentFirstName, ' ', clients.studentLastName)) as id, appointments.location, appointments.subLocation, ...
Select distinct concat(....)
From ....