I'm building a report and exporting it to GSheets. However, instead of running 4 to six calls to BQ (different projects), I'd like to make one call and extract the result as something like
T1.field1 | T1.field2 | T2.field3 | T2.field4 | etc.
The point is that these output data are not related to each other and the sizes of the output tables are different as well.
I thought to have null in the shorter tables.
The only solution I could think of is to add another column with row number and make a full join on the row number.
If you have better solution, I'd love to hear.
Thanks!
instead of joining you can consider union as it is in simplified example below. results are not horizontally layout - but still one call and friendly enough for spreadsheet to manipulate with
SELECT output, field1, field2, field3, field4, field5, field6
FROM
(SELECT 't1' AS output, field1, field2, field3
FROM (SELECT 1 AS field1, 2 AS field2, 3 AS field3)),
(SELECT 't2' AS output, field4, field5,
FROM (SELECT 4 AS field4, 5 AS field5)),
(SELECT 't3' AS output, field6
FROM (SELECT 6 AS field6))
Related
Need help to create query to compare the data and fetch relevant data from table:
Input
Field1
Field2
abc_ID
ID
abc
abc
abc_id_test
test
abc_id_test
abc test
abc_id_test_scenario
scenario
abc_id_test_scenario
cde test
Output
Field1
Field2
abc_id_test_scenario
cde test
If field 2 contains string that matches with field 1 then I need to filter those records.
You can do it using unnest and string_to_array combined to expand a string to a set of rows. then check rows from Field2 not match Field1
with cte as (
select Field1, Field2, unnest(string_to_array(Field2, ' ')) as item
from mytable
)
select field1, Field2
from cte
where Field1 not like concat('%',item,'%')
Demo here
I have 2 tables (A,B).
table A has these fields ( 1,2,3,4,5,6,7,...30).
table B has these fields ( 1,2,3,6,7).
The main table is A - data is inserted into Table A by a sales system .
I need trigger to do this :
Copy a New row inserted to table A and field (3) > 1 and field (7)!=''
To table B.
Note : there are huge data inserts to table A (at peak times) for that need code not effect performance.
In SQL Server, I would phrase this as;
create trigger trig_tableA_insert on tableA after insert
as begin
insert into tableB (Field1, Field2, Field3, Field6, Field7)
select i.Field1, i.Field2, i.Field3, i.Field6, i.Field7
from inserted i
where i.field3 > 1 and i.field7 <> '';
end;
This is safe for statements that insert multiple rows at one time.
If you have lots of inserts, I wonder if this is the best approach. Presumably, you need the data right away in tableB, because triggers incur overhead.
here's your trigger. adding below condition will not insert data to your tableB.
create trigger [t_TableA]
on tableA
after [insert]
as
begin
if ((select 1 from inserted where field3 > 1 and coalesce(field7, '') != '') != 1)
begin
return;
end
insert into tableB (Field1, Field2, Field3, Field6, Field7)
select Field1, Field2, Field3, Field6, Field7 from inserted
end
I have a field which holds a short list of ids of a fixed length.
e.g. aab:aac:ada:afg
The field is intended to hold at most 5 ids, growing gradually. I update it by adding from a similarly constructed field that may partially overlap with my existing set, e.g. ada:afg:fda:kfc.
The field expans when joined to an "update" table, as in the following example.
Here, id_list is the aforementioned list I want to "merge", and table_update is a table with new values I want to "merge" into table1.
insert overwrite table table1
select
id,
field1,
field2,
case
when (some condition) then a.id_list
else merge(a.id_list, b.id_list)
end as id_list
from table1 a
left join
table_update b
on a.id = b.id;
I'd like to produce a combined field with the following value:
aab:aac:ada:afg:fda.
The challenge is that I don't know whether or how much overlap the strings have until execution, and I cannot run any external code, or create UDFs.
Any suggestions how I could approach this?
Split to get arrays, explode them, select existing union all new, aggregate using collect_set, it will produce unique array, concatenate array into string using concat_ws(). Not tested:
select concat_ws(':',collect_set(id))
from
(
select explode(split('aab:aac:ada:afg',':')) as id --existing
union all
select explode(split('ada:afg:fda:kfc',':')) as id --new
);
You can use UNION instead UNION ALL to get distinct values before aggregating into array. Or you can join new and existing and concatenate strings into one, then do the same:
select concat_ws(':',collect_set(id))
from
(
select explode(split(concat('aab:aac:ada:afg',':','ada:afg:fda:kfc'),':')) as id --existing+new
);
Most probably you will need to use lateral view with explode in the real query. See this answer about lateral view usage
Update:
insert overwrite table table1
select concat_ws(':',collect_set(a.idl)) as id_list,
id,
field1,
field2
from
(
select
id,
field1,
field2,
split(
case
when (some condition) then a.id_list
when b.id_list is null then a.id_list
else concat(a.id_list,':',b.id_list)
end,':') as id_list_array
from table1 a
left join table_update b on a.id = b.id
)s
LATERAL VIEW OUTER explode(id_list_array ) a AS idl
group by
id,
field1,
field2
;
I have two tables:
FirstField | SecondField | ThirdField
FirstValue SecondValue ThirdValues
----------------------------------------------
FirstField | SecondField | ThirdField
OtherValue1 OtherValue2 OtherValue3
What I need it to add those two tables together into one SQL query. They can not be joined as I don't have anything to join them on and that's not what I want. I want my new table to look like:
FirstField | SecondField | ThirdField
FirstValue SecondValue ThirdValues
OtherValue1 OtherValue2 OtherValue3
This may be very simple but I am new to SQL and have been unable to find any help elsewhere.
Try UNION ALL:
SELECT FirstField ,SecondField ,ThirdField
FROM Table1
UNION ALL
SELECT FirstField ,SecondField ,ThirdField
FROM Table2
If you want to remove duplicate rows use UNION instead.
SELECT FirstField ,SecondField ,ThirdField
FROM Table1
UNION
SELECT FirstField ,SecondField ,ThirdField
FROM Table2
Have a lok at using a UNION/UNION ALL
Combines the results of two or more queries into a single result set
that includes all the rows that belong to all queries in the union.
The UNION operation is different from using joins that combine columns
from two tables.
So something like
SELECT Field1,
Field2,
...
Fieldn
FROM Table1
UNION ALL
SELECT Field1,
Field2,
...
Fieldn
FROM Table2
Provided that the column types and count match, use UNION ALL:
SELECT * FROM T1
UNION ALL
SELECT * FROM T2
I have a piece of code that runs on a variety of databases. It simply runs a configurable sql query which returns a number of rows. From each row, i pull some text and a number to create a new object. Our latest client has decided to put all the text number combinations in a single row of the database i.e
text_1, num_1, text_2, num_2, text_3, num_3
Is there a clever way I can query this to return
text_1,num_1
text_2,num_2
text_3,num_3
so that I don't have to re-code the section for this client.
EDIT:
(Different databases means different RDBMS)
(the commas delimit different columns within a table)
SELECT
CASE row.id WHEN 1 THEN field1
WHEN 2 THEN field3
ELSE field5
END AS new_field_1,
CASE row.id WHEN 1 THEN field2
WHEN 2 THEN field4
ELSE field6
END AS new_field_2
FROM
myTable
CROSS JOIN
(SELECT 1 AS id UNION ALL SELECT 2 UNION ALL SELECT 3) AS row
This should work for most, though still need a little modification (Such as adding 'FROM dual' in the UNIONs for Oracle...)
Alternatively, just UNION three queries together...
SELECT field1, field2 FROM myTable
UNION ALL
SELECT field3, field4 FROM myTable
UNION ALL
SELECT field5, field6 FROM myTable
You can create a function/SP to return a ResultSet the way you need.