un-struct in big query - database

I have a table with some struct data types that I can access but would like it as columns.
select
consignment id,
user
from tbl
What I currently have
select
consignment id
, user.name
, user.email
, user.externalId
from tbl
What I want
I was able to get it by just calling every key of user but on a table with hundreds of columns that would be terrible

use below
select
consignment id,
user.*
from tbl

Related

Show accounts with multiple contacts to as separate columns rather than rows?

Suppose, I have a table of contacts.
That table has contact IDs and Account IDs
So if I do
Select ContactID,AccountID From table
I get this:
Instead, I want to see this:
Is this plausible?
With two and only two contacts par account, aggregation seems like a straight-forward option:
select account_id, min(contactId) contactId1, max(contactId) contactId2
from mytable
group by account_id
If some accounts have 2 contacts and others have just 1, then:
select
account_id,
min(contactId) contactId1,
case when count(*) > 1 then max(contactId) end contactId2
from mytable
group by account_id

Choose 2 Random Values from 2 Separate Columns SQL

I am having to prepare test data to send to a 3rd party however I don't wish to send the customers real name nor do I wish to send their real date of birth.
I could solve the D.O.B issue by just randomly increasing the DOB by several years. However the name is different, is there anyway I can have a list of say 10 customer names and just choose a different Firstname and Surname each time.
I wish to mix and match the names however so it essentially randomly picks 1 firstname and then randomly picks a lastname and puts them together on the same line.
SELECT TOP 1 opde.first_name
FROM Table AS opde
ORDER BY NEWID()
This will return a random first name each time, but if I put the surname column in it will also return the matching surname, I don't want that I want a random surname from the list.
I tried doing this via a UNION but you can't do an ORDER BY NEWID() in the UNION.
Cheers.
I think this one might help...
WITH fn AS
(
SELECT TOP 1 opde.first_name
FROM Table AS opde
ORDER BY NEWID()
),
sn AS
(
SELECT TOP 1 opde.surname
FROM Table AS opde
ORDER BY NEWID()
)
SELECT first_name, surname
FROM fn
CROSS APPLY sn;
In the fn subquery you select a random first name. In the sn you do the same but with an surname.
With the cross apply you combine those two results
You may use a union of subqueries, each of which uses order by with NEWID:
SELECT first_name
FROM
(SELECT TOP 1 opde.first_name FROM Table AS opde ORDER BY NEWID()) t1
UNION ALL
SELECT first_name
FROM
(SELECT TOP 1 opde.first_name FROM Table AS opde ORDER BY NEWID()) t2;
Demo

SELECTing data using a Postgres Array

I have a table that contains a column user_ids which is a Postgres Array.
I need to select all messages from another table where the column user_id is one of the ids in the given array.
In Psuedo-sql:
select users.*
from users
where id IN a_postgres_array
Any ideas?
You could use the ANY operator. From your sample:
select users.*
from users
where id =ANY(a_postgres_array)
When using two tables, it could be a JOIN, something like:
SELECT users.*
FROM users INNER JOIN table_with_array ON users.id =ANY(table_with_array.a_postgres_array)
select users.*
from users
where id IN (
select unnest(a_postgres_array)
from t
where columnX = some_value
)

Making a query that only shows unique records

I have a table where duplicate entries in one of the columns is possible (emailAddress - some couples share them) and I would like to send email newsletters to them. Is there a way to make a select query where it only shows one copy of the email address if there are multiple?
If you need only emailAddress it is quite simple:
select distinct emailAddress from <YourTableNameHere>
Edited according to request in comments.
If you want to choose both distinct emailAddress and ANY customerName related to it then you must somehow tell SQL how to choose the customerName. The easiest way is to select i.e. MIN(customerName), then all other (usually those that are later in alphabet but it actually depends on collation) are discarded. Query would be:
select emailAddress, min(customerName) as pickedCustomerName
from <YourTableNameHere>
group by emailAddress
You can use the DISTINCT keywprd, or you can GROUP BY.
SELECT DISTINCT email
FROM table
Or
SELECT email, Count(ID)
FROM table
GROUP By email

Get distinct values of a record but have other records as well in the select statement

I have a table with timestamp of page views of a particular page by a user. I need to List of unique pages viewd by user and if the user visits same page multiple time I need to fetch the latest record of the lot.
for example: for table tblUserPageViews, i have columns
PageURL, TimeStamp,UserID,UserPageViewsID
I have tried the obvious
SELECT Distinct(PageURL),TimeStamp,UserID,UserPageViewsID FROM tblUserPageViews
this will not work
Any ideas much appreciated.
Thanks.
Try this
SELECT PageURL, UserID, UserPageViewsID, MAX(TimeStamp) TimeStamp
FROM tblUserPageViews
GROUP BY PageURL, UserID, UserPageViewsID
SELECT MAX(PageURL),
MAX(TimeStamp),
MAX(UserID),
SUM(UserPageViewsID)
FROM tblUserPageViews
GROUP BY PageURL
SELECT DISTINCT works in the whole row, not in one particular column. If you need just the userId, pageURL and maximum timestamp, a simple GROUP BY is enough:
SELECT
UserID
, PageURL
, MAX(TimeStamp) AS MaxTimeStamp
FROM
tblUserPageViews
GROUP BY
UserID
If you want to show other columns, too, you could use this "wrapping" of the above query into a join with the original table:
SELECT
t.PageURL,
, t.TimeStamp
, t.UserID
, t.UserPageViewsID
FROM
tblUserPageViews AS t
JOIN
( SELECT
UserID
, PageURL
, MAX(TimeStamp) AS MaxTimeStamp
FROM
tblUserPageViews
GROUP BY
UserID
) AS tm
ON
tm.UserID = t.UserID
AND
tm.PageURL = t.PageURL
AND
tm.MaxTimeStamp = t.TimeStamp
If you are on the latest versions of SQL-Server (2005 or later), you could also use window functions to write this.

Resources