postgresql full join migrate the first two columns - sql

I have two datasets like,
A B
1 hello
2 hi
3 bye
And:
A C
2 yo
3 gutentag
4 seeya
I'm using FULL JOIN on column A to have the both dataset in one table... But I got this:
A A B C
1 hello
2 2 hi yo
3 3 bye gutentag
4 seeya
Instead of this I would like to get the two A column in one, liket this:
A B C
1 hello
2 hi yo
3 bye gutentag
4 seeya
I know this must be a basic question... But still, I can't solve it. :-)
My code is:
SELECT dataset1.A, dataset2.A, dataset1.B, dataset2.B FROM dataset1
JOIN dataset2
ON (dataset1.A = dataset2.A);

select a, d1.b, d2.c
from
d1
full join
d2 using (a);
Check the using clause: http://www.postgresql.org/docs/current/static/sql-select.html#SQL-FROM
USING implies that only one of each pair of equivalent columns will be included in the join output

Related

How to pivot wider in SQL or use a more "dynamic" form of the LEAD function?

I have a table that looks as follows:
Policy Number Benefit Code Transaction Code
1 A 2
1 B 1
2 A 3
3 A 2
1 C 2
For analysis purposes, it would be much more convenient to have the table in the following form:
PN BC 1 TC 1 BC 2 TC 2 BC 3 TC 3
1 A 2 B 1 C 2
2 A 3 NULL NULL NULL NULL
3 A 2 NULL NULL NULL NULL
I believe this can be done, for example, in R using the tidyverse package, where the concept is basically pivoting the table from long-form to wide-form. Now, I know that I could possibly use the LEAD function in SQL, but the problem/issue is that I do not know how many benefit codes and transaction codes each policy has (i.e. they are not fixed).
Thus, my query is:
How can I "pivot wider" my table to achieve something like the above?
Other than "pivoting wider", is there a more dynamic form of the LEAD function in SQL, where it takes all subsequent rows of a group (in my case, each policy number) and puts them in new columns?
Any intuitive explanations or suggestions will be greatly appreciated :)

Using Exclude/Intersect in the same Table

i have this table:
Line Group
1 A
2 A1
3 A2
4 A2
5 ALA
i wanna make a query that selects only the lines that contain a,a1,a2 but not the one named ALA
i tried a query like this:
select linea from table where group like'%A%'
Except
select linea from table where group ='ALA'
But didnt worked what can i do to get the data i need?
Ty in advance

SQL Getting multiple rows from a single row

I need to accomplish the following :
I have a table with multiple column (c1, c2, c3, c4 ... cn).
I want a query that would return multiple rows in the following fashion (r1 r2 .. rx are the rows in the original table) :
r1c1 r1c2 r1c3
r1c4 r1c5 r1c6
...
r1cn-2 r1cn-1 r1cn
r2c1 r2c2 r2c3
r2c4 r2c5 r2c6
...
r2cn-2 r2cn-1 r2cn
...
rxc1 rxc2 rxc3
rxc4 rxc5 rxc6
...
rxcn-2 rxn-1 rxcn
I know I can use unions and repeat basically the same query n times, but I need to use that query in a web based reporting system that I have no control over and the query is to big for the maximum number of characters allowed in queries.
Any suggestions ?
Thank you !
EDIT : FYI I'm building a report in a report tool I can't change using a database I can't change. So using custom functions/procedures is not a solution. It has to be a PL-SQL query.
To be more specific, i need to have multiple rows from the original row, lets say row 1 is
a b c d e f h i j
and row 2 is
1 2 3 4 5 6 7 8 9
then I would get the following table with 3 columns :
a b c
d e f
h i j
1 2 3
4 5 6
7 8 9
So number 1, if you have a set number of columns in the original table that is divisible by 3, you can just do that many UNION ALL.
Your only other options are pivot or a pointer, neither of which is going to be any better.
The simple case when n is divisible by 3 just use rownum and union:
WITH T1 AS
(
SELECT rownum as rn,1 as tNum, c1 as s1,c2 as s2,c3 as s3 FROM T
UNION ALL
SELECT rownum as rn,2 as tNum, c4 as s1,c5 as s2,c6 as s3 FROM T
UNION ALL
SELECT rownum as rn,3 as tNum, c7 as s1,c8 as s2,c9 as s3 FROM T
)
SELECT s1,s2,s3 FROM T1
ORDER BY rn,tNum
SQLFiddle demo

Oracle query to link records from same table which maps to mapping table

Apologies for the horrible question title,not sure how to articulate it better.
So to start out.
**Table Dummy_Table**
id description filter_key
1 Test Record1 filterkey1
2 Test Record2 filterkey1
3 Test Record1 filterkey2
4 Test Record2 filterkey2
The records with filterkey1 map to a table like this
**Table Mapping_table**
Dummy_Table_id someother_key (one(Dummy_Table_id) to many(someother_key)
1 x
1 y
1 z
1 r
2 y
2 r
Now : In a query I map the id's to each other in the Dummy_Table using the description,so I end up with a resultset like this
id_for_filter_key1 id_for_filterkey2
1 3
2 4
Ok,thats all good and well,it's the next step I'm having a issue with.I need to add records to Table Mapping_table which should end up looking like this
**Table Mapping_table**
Dummy_Table_id someother_key
3 x
3 y
3 z
3 r
4 y
4 r
So in essence whatever the id is for filterKey1 I would like to apply it's someother_key to the id's with filterkey2 (filterKey1 and filterkey2 relate to each other with their descriptions)
Now I don't know if I'm over complicating this.I'll tell you what my problem is.
I have records in the database with filterkey1 which map to the mapping table.Afterwords I added the records with filterkey2.These rows are duplicates just with another filter key.Now I need to apply the same mappings to the records with filterkey2
Changing the table structure is not a option atm.I need to give the DBA a insert query to achieve this.
Many thanks in advance.
This query gives missing values:
SELECT d.id_for_filterkey2, m.someother_key
FROM Mapping_table m
JOIN Dummy_Table d ON m.Dummy_Table_id = d.id_for_filter_key1
Demo: http://sqlfiddle.com/#!4/61ddfe/2
When we have missing values, then we can merge them into Mapping_table:
MERGE INTO Mapping_table m
USING( copy-the-above-query-and-paste-it-here) x
ON (x.id_for_filterkey2 = m.Dummy_Table_id)
WHEN NOT MATCHED THEN
INSERT( Dummy_Table_id, someother_key )
VALUES( x.id_for_filterkey2, x.someother_key );
Demo: http://sqlfiddle.com/#!4/d74304/3

Why does this query return "incorrect" results?

I have 3 tables:
'CouponType' table:
AutoID Code Name
1 CouT001 SunCoupon
2 CouT002 GdFriCoupon
3 CouT003 1for1Coupon
'CouponIssued' table:
AutoID CouponNo CouponType_AutoID
1 Co001 1
2 Co002 1
3 Co003 1
4 Co004 2
5 Co005 2
6 Co006 2
'CouponUsed' table:
AutoID Coupon_AutoID
1 2
2 3
3 5
I am trying to join 3 tables together using this query below but apparently I am not getting right values for CouponIssued column:
select CouponType.AutoID, Code, Name, Count(CouponIssued.CouponType_AutoID), count(CouponUsed.Coupon_AutoID)
from (CouponType left join CouponIssued
on (CouponType.AutoID = CouponIssued.CouponType_AutoID))
left join CouponUsed
on (couponUsed.Coupon_AutoID = CouponIssued.AutoID)
group by CouponType.AutoID, code, name
order by code
The expected result should be like:
**Auto ID Code Name Issued used**
1 CouT001 SunCoupon 3 2
2 CouT002 GdFriCoupon 3 1
3 CouT003 1for1Coupon 0 0
Thanks!
SELECT t.AutoID
,t.Code
,t.Name
,count(i.CouponType_AutoID) AS issued
,count(u.Coupon_AutoID) AS used
FROM CouponType t
LEFT JOIN CouponIssued i ON i.CouponType_AutoID = t.AutoID
LEFT JOIN CouponUsed u ON u.Coupon_AutoID = i.AutoID
GROUP BY 1,2,3;
You might consider using less confusing names for your table columns. I have made very good experiences with using the same name for the same data across tables (as far as sensible).
In your example, AutoID is used for three different columns, two of which appear a second time in another table under a different name. This would still make sense if Coupon_AutoID was named CouponIssued_AutoID instead.
change count(Coupon.CouponType_AutoID) to count(CouponIssued.CouponType_AutoID) and count(Coupon.Coupon_AutoID) to count(CouponUsed.Coupon_AutoID)