I have to merge two columns from two unrelated tables with the same number of rows in another table, like
Table A:
AColumn
'ABC'
'152'
'XXX'
Table B:
BColumn
'FF'
'CD'
'91'
Expected result for the destination table (table C):
CColumn1 CColumn2
'ABC' 'FF'
'152' 'CD'
'XXX' '91'
Apparently this looks very simple but I can't find a way to achieve it.
My attempt would be something like:
SELECT A.AColumn as CColumn1, B.BColumn as CColumn2 into C
FROM A INNER JOIN B ON 1=1
but this obviously generates all the possible combinations over the elements, while I just want the first row from A matched with the first row from B, the second row with the second row, etc.
Any help?
You need to add a row_number to each table and join on that, here is an example using two CTEs:
with a as (
select AColumn, row_number() over(order by (select null)) rn
from Table1
),
b as (
select BColumn, row_number() over(order by (select null)) rn
from Table2
)
select a.AColumn, b.BColumn
from a full outer join b
on a.rn = b.rn
Sql Fiddle: http://sqlfiddle.com/#!18/291c7/4
Related
I have used lateral flatten logic in Snowflake in the below query. The query works up to alias A.
I'm getting invalid identifier error when I use the join condition
based on the common column. ON B.product_id=A.product_id
SELECT A.ID, INDEX, purchase_list,
CASE WHEN INDEX = 1 and purchase_list NOT IN('121=find-values','122=find_results','123=item_details','',' ')
THEN purchase_list END as item_no
FROM (SELECT ID,index,d.value::string AS purchase_list FROM (
SELECT ID,c.value::string AS purchase_list
FROM table_1,lateral flatten(INPUT=>split(po_purchase_list, '|')) c
),
LATERAL flatten(INPUT=>split(purchase_list, ';')) d
) A -- The query would be correct till here
JOIN
table_2 B -- This is the table I need to join with table_1
ON B.product_id=A.product_id
WHERE date='2022-03-03'
AND b.item_src NOT IN('0','1','3','4')
from the error message it looks like it is not able to find the column product_id in one of the tables or CTE , can you include the column product_id in your SELECT statement for table A, and see if it works.
i have two inputs:
a. Table A with 3 columns: a ,b , c - with 7 rows
b. Table B with an array column d , the array has 7 values.
Is there a way to "merge" the table A and TABLE B in a query - so that the first row of A and the first cell value of B will printed in the same row ?
Input:
For example:
Table A- Column 1
a
b
c
Table A- Column 2
d
e
f
Table b - column 1 (and only)
k
r
j
OUTPUT
should be three columns:
two first columns : column a, b (from table a)
third column - which is column 1 from table 2
You can use Flatten to convert your array into a table. Then you just need to define ordering and how to join them together.
Here's an example, where I use a ROW_NUMBER() to provide an ordering. And since I added it to both tableA and the flattened tableB, it can also be used to join the records together.
If you have IDs for ordering or joining, then that might be slightly cleaner, but with the simple columns provided in the example, you need to do something like this to line up the array values to the table rows.
with tA as (
select col1, col2,
ROW_NUMBER() OVER(ORDER BY col1) rnum
from tableA
)
,tB as (
select
x.value::string col1,
ROW_NUMBER() OVER(ORDER BY 1) rnum
from tableB ,
lateral flatten(input => array) x
)
SELECT a.col1, a.col2, b.col1
FROM tA a
JOIN tB b
ON a.rnum = b.rnum;
There is no "first row" in databases. There is a first with respect to an order you place on the data. Thus there a number of way to get just the "first row" of table A and table B.
On is to only select the first rows, I will use CTE but it can be done in a sub-select also. Via a QUALIFY and ROW_NUMBER, and to make it 'stable' I will use the selected output column. After that to JOIN the two tables, I will use a CROSS-JOIN, but given there are only one row from both CTE's this will give just one output row. But this does not feel like what you want.
WITH first_from_table_a AS (
SELECT column1, column2
FROM table_a
QUALIFY ROW_NUMBER() OVER (ORDER BY column1) = 1
), first_from_table_b AS (
SELECT column1
FROM table_b
QUALIFY ROW_NUMBER() OVER (ORDER BY column1) = 1
)
SELECT a.column1, a.column2, b.column1
FROM first_from_table_a AS a
CROSS JOIN first_from_table_b AS b
The problem with this is, if there are other things you are want to do this over it doesn't scale.
FIRST_VALUE is a function that could also help, if you join your data on some other schema, and want to chose a value from a larger set, but really the problem needs to be clarified more.
Another way to consider your question is to use the same ROW_NUMBER idea, and join on those, thus:
WITH first_from_table_a AS (
SELECT column1,
column2,
ROW_NUMBER() OVER (ORDER BY column1) AS rn
FROM table_a
), first_from_table_b AS (
SELECT column1,
ROW_NUMBER() OVER (ORDER BY column1) AS rn
FROM table_b
)
SELECT a.column1, a.column2, b.column1
FROM first_from_table_a AS a
JOIN first_from_table_b AS b
ON a.rn = b.rn
ORDER BY a.rn
I'm trying to basically combine the columns from two outputs into one row.
Here's one example:
SELECT * FROM (SELECT 'Today' AS Txt) t1
FULL OUTER JOIN (SELECT * FROM (SELECT GETDATE() AS D) t2)
-- desired result is one row with a 'Txt' column with value 'Today' and a 'D' column with the result of the GETDATE function
And another:
SELECT * FROM (SELECT * FROM dbo.myTableFunc()) t1 -- returns 5 rows
FULL OUTER JOIN (SELECT * FROM (SELECT * FROM dbo.myOtherTableFunc())) t2 -- also returns 5 rows
The thing I cannot figure out how to do is to do the "outer join" on the two subqueries. In the first example, I'm basically trying to combine the result of two scalars into a single row result. In the second I'm trying to take two tables, each with five rows, and combine their columns, without any relationship between the data in the two tables.
I'm trying to do the above in a UDF and also in a view, so anything that involves creating temporary tables will not work.
In both of the above cases I get syntax errors around the closing ) signs in the outer join.
You're just missing the join conditions. in the first example, your join condition is "always", or 1 = 1:
SELECT * FROM (SELECT 'Today' AS Txt) t1
FULL OUTER JOIN (SELECT * FROM (SELECT GETDATE() AS D) t2) t2 on 1=1
In the second example you don't want any relationship between the rows in each data set - well, if you want to join them then there needs to be SOME relationship, even if it's spurious. Using a row number like this would work (assumes you have a unique column called Id in both tables):
select * from (
select row_number() over (order by Id asc) rn, * from dbo.myTableFunc()
) t1
full join (
select row_number() over (order by Id asc) rn, * from dbo.myOtherTableFunc()
) t2 on t1.rn=t2.rn
In a single database, I have three tables as below:
I want to concatenate them in some single table, any suggestion?
If I am understanding correctly your answer you want something like this:
CREATE TABLE COMBINED (/*Insert the set of fields here*/);
GO
INSERT INTO COMBINED
SELECT Table1.ProposalId
, /*all other Table1 fields*/
, Table2.ProposalId
/*all other Table2 fields*/
, Table3.ProposalId
, /*all other Table2 fields*/
FROM Table1
FULL JOIN Table2
ON Table1.ProposalId = Table2.ProposalId
FULL JOIN Table3
ON Table1.ProposalId = Table3.ProposalId;
This will match the rows with the same proposal id (but keep the all the its values as proposalid_1,proposalid_2... and for those that do not match will bring the full row and NULL for every other fields of the rest of the tables.
Thanks for your help the issue has been solved.
SELECT mtlreq.proposalid, mtlreq.prp_mtlreq_taskgrp,mtlreq.prp_mtlreq_taskcode,mtlreq.prp_mtlreq_itemcode,mtlreq.prp_mtlreq_rateper,mtlreq.prp_mtlreq_qty,mtlreq.prp_mtlreq_Inter_MaterCost,mtlreq.prp_mtlreq_UOM,mtlreq.item_short_desc, resreq.proposalid,resreq.prp_resreq_taskcode ,resreq.prp_resreq_resource,resreq.prp_resreq_usage,resreq.prp_resreq_uom,resreq.prp_resreq_rate,resreq.prp_resreq_overhd_pers
FROM (
SELECT proposalid,prp_mtlreq_taskgrp,prp_mtlreq_taskcode,prp_mtlreq_itemcode,prp_mtlreq_rateper,prp_mtlreq_qty,prp_mtlreq_Inter_MaterCost,prp_mtlreq_UOM,item_short_desc,
ROW_NUMBER() OVER (ORDER BY proposalid) AS rn
FROM prjdet_prp_taskwork_mtlreq ) AS mtlreq
FULL OUTER JOIN (
SELECT proposalid,prp_resreq_taskcode ,prp_resreq_resource,prp_resreq_usage,prp_resreq_uom,prp_resreq_rate,prp_resreq_overhd_pers,
ROW_NUMBER() OVER (ORDER BY proposalid) AS rn
FROM prjdet_prp_taskwork_resreq) AS resreq
ON mtlreq.rn = resreq.rn
FULL OUTER JOIN (
SELECT proposalid,mtprp_delv_lineno,mtprp_delv_itemcode,mtprp_delv_cost,mtprp_delv_linelevelmrg,mtprp_delv_proposedamt,
ROW_NUMBER() OVER (ORDER BY proposalid) AS rn
FROM prjproposal_delidtl ) AS delidtl
on mtlreq.rn = delidtl.rn and resreq.rn=delidtl.rn
I have reports that pull 50 random records. i would like to insert a blank Row in the output between each row of data. for example, Rows 1,3,5,7... are populated with data, and even number rows are empty.
Thanks
CROSS APPLY with NULL valued table gives equal number of rows as original table.
Now we can generate ROW_NUMBER for two SELECTs and sort it by row number to get alternate values.
select C.id, C.name, ROW_NUMBER() OVER ( ORDER BY C.id) as seq from TableC C
UNION ALL
SELECT T.id, T.name, seq as seq
FROM
(
select T.id, T.name ,ROW_NUMBER() OVER ( ORDER by C.id ) as seq from TableC C
cross apply ( select NULL as id,NULL as name ) T
) T
ORDER BY seq
A very simple solution could be :
Select id+Temp id, name+Temp name from TableA A
Cross Apply
(select '' as 'Temp'
union all
Select null) X
If you have large number of columns, then create the concatenation of column_name + temp dynamically and use that in dynamic sql
for Demo Click on --> DEMO