return columns vertically - sql

Let's say I have a simple select query that returns the following:
ID Name1 Name2 Description1 Description2 Notes1 Notes2
1 A B AA BB AAA BBB
2 C D CC DD CCC DDD
and I want to return dataset as follows:
ID ColumnName 1st 2nd
1 Name A B
1 Description AA BB
1 Notes AAA BBB
2 Name C D
2 Description CC CC
2 Notes DDD DDD
Any way of doing that in sql server 2008-r2?
Looks like it's a job for PIVOT but a'm confused on how to achieve this with PIVOT

You can use this, assuming the values are static or not so numerous that patching it up with your actual values isn't too painful:
SELECT ID, 'Name' ColumnName, Name1 '1st', Name2 '2nd'
FROM YourTable
UNION
SELECT ID, 'Description' ColumnName, Description1 '1st', Description2 '2nd'
FROM YourTable
UNION
SELECT ID, 'Notes' ColumnName, Notes1 '1st', Notes2 '2nd'
FROM YourTable
Yet another great example of why data normalization is so important.

Related

SQL Optimization - Match Analysis sorting matched pairs

Scenario :
Matching algorithm has identified ID1 AND ID2 have matched.I need to do further analysis on the matching. For that I need to reduce the number of rows in output and sorted correctly.
This input is just sample and subset. Having thousands of actual records makes this task difficult.
INPUT:
ID1
NAME1
ID2
NAME2
222
SIM
333
SIM
111
SAM
222
SIM
111
SAM
333
SIM
111
SAM
444
SOM
111
SAM
555
SAM
222
SIM
444
SOM
222
SIM
555
SAM
333
SIM
444
SOM
444
SOM
555
SAM
013
AAA
014
BBB
021
SUB
111
SAM
010
CCC
011
DDD
023
SOB
333
SIM
EXPECTED OUTPUT:
ID
NAME
111
SAM
222
SIM
333
SIM
444
SOM
555
SAM
021
SUB
023
SOB
013
AAA
014
BBB
010
CCC
011
DDD
I need to ensure that output should have ID should have distinct records of ID1 and ID2 combined which is still fine as I can do distinct and union.
Tricky part is to ensure sorting of data in ouptput. I need to keep the rows that are similar in order.
Example :
111,222,333,444,555,021,023 have similar matching ID's in ID1 and ID2 and have to be sorted together. Within this group, the sorting order doesn't matter, just they need to be together. Similarly there could be many such groups.
The rest whenever only 1 pair is there, just need to sort them together like 013,014 and 010,011 and so on
Can anyone help me with this query?
For the case of knowing the patterns a priori,
union + order by case when would go here:
select * from (
select ID1, NAME1 from tab1 union
select ID2, NAME2 from tab1 ) a
order by case when NAME1 like '%S' then '' else NAME1 end;
SQL Fiddle on your data here
To group based on just ID1 & ID2, added a sorter column,
concatenating the IDs of each row with least & greatest on MySQL:
select * from (
select concat(least(ID1, ID2), greatest(ID1,ID2)) sorter, ID1, NAME1 from tab1 union
select concat(least(ID1, ID2), greatest(ID1,ID2)) sorter, ID2, NAME2 from tab1 ) a
group by ID1
order by sorter
or with case when on SQL Server:
select min(sorter) sorter, ID1, NAME1 from (
select concat(case when ID1<ID2 then ID1 else ID2 end, case when ID1>ID2 then ID1 else ID2 end) sorter, ID1, NAME1 from tab1 union
select concat(case when ID1<ID2 then ID1 else ID2 end, case when ID1>ID2 then ID1 else ID2 end) sorter, ID2, NAME2 from tab1 ) a
group by ID1, Name1
order by min(sorter)

oracle sub query or union

I have a case table as follows:
caseId
caseType
last_name
first_Name
aCaseStatus
bCaseStatus
created_by
1
P
test
a
0
0
1
2
M
test1
b
1
2
2
3
M
test2
c
1
3
1
aCaseStatus
id
descr
1
aaa
2
bbb
3
ccc
bCaseStatus
id
descr
1
xxx
2
yyy
3
zzz
I have a query like below
select c.case_id caseId, c.last_name lastName, c.first_name firstName,
caseType caseType,
acaseStatus||','||bCaseStatus as caseStatus
from cases c
join aCaseStatus acs
on acs.id = c.aCaseStatus
left outer join bCaseStatus bcs
on bcs.id = c.bCaseStatus
where (c.created_by = 1 ) and ( c.aCaseStatus in (1) or c.bCaseStatus in (0)) and c.caseType='M'
UI has a display like below
caseId
Name
caseStatus
2
b,test1
aaa, yyy
3
c,test2
aaa, zzz
When you look at the UI display caseStatus is a combination of aCaseStatus, bCaseStatus.
Also, the UI table has a search functionality wherein caseStatus is a multi-select dropdown field.
This dropdown has a combination of aCaseStatus and bCaseStatus.
Dropdown is as below:
CaseStatus
aaa
bbb
ccc
xxx
yyy
zzz
Note: aCaseStatus alone is a mandatory field so I have given an inner join, however, bCaseStatus is not so I have given a left outer join.
When the user selects aaa, UI should display:
caseId
Name
caseStatus
2
b,test1
aaa
3
c,test2
aaa
when the user selects aaa, xxx UI should display:
caseId
Name
caseStatus
2
b,test1
aaa, xxx
3
c,test2
aaa
But when I use the above query for aaa selection I get:
caseId
Name
caseStatus
2
b,test1
aaa, xxx
3
c,test2
aaa
I do not want the xxx to be displayed even though caseId has xxx caseStatus. How should I change the query to achieve this? Should I write a union query one for aCaseStatus and the other for bCaseStatus or is there any other way this can be achieved?
Suggestions, please?

Oracle 11g - Creating a side by side comparison of table comlumn data

I have a query where I need to extract data in a regular table and put two rows of data into a single row.
I have rows that consist of
StudentID AUDIT_ACTN Audit_Date .....
aaa A 01/01/2010
aaa A 03/04/2011
aaa A 02/02/2013
aaa D 09/10/2010
aaa D 05/06/2011
aaa D 06/07/2013
aaa A 11/12/2014~
bbb A 01/01/2010
bbb A 03/04/2011
bbb A 02/02/2013
bbb D 09/10/2010
bbb D 05/06/2011
bbb D 06/07/2013
bbb A 11/12/2014~
I want output like this
StudentID AUDIT_ACTN Audit_Date StudentID AUDIT_ACTN Audit_Date
aaa A 01/01/2010 aaa D 09/10/2010
aaa A 03/04/2011 aaa D 05/06/2011
aaa A 02/02/2013 aaa D 06/07/2013
aaa A 11/12/2014 NULL NULL NULL
bbb A 01/01/2010 bbb D 09/10/2010
bbb A 03/04/2011 bbb D 05/06/2011
bbb A 02/02/2013 bbb D 06/07/2013
bbb A 11/12/2014 NULL NULL NULL
The A & D data rows are related, a= add the something to the record and d = delete something from the record (something is an indicator). These is logical in that you must add something before you delete it and you cannot add it twice, without deleting it first.
My current script is probably going down the wrong track but here goes;
select a.StudentId,a.Audit_Date,a.AUDIT_ACTN,d.StudentId,Audit_Date,d.AUDIT_ACTN,
from table a
join
(select *
from
(Select StudentId, Audit_Date,AUDIT_ACTN
from table b
Where b.AUDIT_ACTN='D'
order by Audit_Date
)
where rownum=1
) d on a.StudentId = d.StudentId
and a.AUDIT_ACTN='A'
and Select * from (Select Audit_Date
Order by a.StudentId, a.Audit_Date
I know this is wrong but where do I go from here. If anyone can help and point me in the right direction. It would be appreciated.
My current attempts bring me zero rows, when I take out the rownum it brings me a x join returning 12 rows in this case.
thanks
Roger
I think you need aggregate function like below
select
A.StudentId,A.Audit_Date,A.AUDIT_ACTN,
D.StudentId,D.Audit_Date,D.AUDIT_ACTN
from
(Select StudentId, Audit_Date,AUDIT_ACTN,ROW_NUMBER()
OVER (PARTITION BY StudentId order by audit_date) rn
from table b
Where b.AUDIT_ACTN='D'
) D
FULL OUTER JOIN
(Select StudentId, Audit_Date,AUDIT_ACTN,ROW_NUMBER()
OVER (PARTITION BY StudentId order by audit_date) rn
from table b
Where b.AUDIT_ACTN='A'
) A
on A.rn = D.rn and A.StudentId = B.StudentId
I hope this will work

Append tables in SQL

If I have the two following tables,
Table1
ItemNo Desc Order Number Qty S_Date Location
AA AA AAA A AA/AA/AAAA AAAA
BB BB BBB B BB/BB/BBBB BBBB
CC CC CCC C CC/CC/CCCC CCCC
Table 2
M_Order Item M_Date Total
XXX X XX/XX/XXXX XX
YYY Y YY/YY/YYYY YY
Can anyone advice me how to get the following table please.
Result Table
ItemNo Desc Order Number Qty S_Date Location M_Date Total
AA AA AAA A AA/AA/AAAA AAAA
BB BB BBB B BB/BB/BBBB BBBB
CC CC CCC C CC/CC/CCCC CCCC
X XXX XX/XX/XXXX XX
Y YYY YY/YY/YYYY YY
Thanks
You can do this with a full outer join trick:
select t1.*, t2.*
from table1 t1 full outer join
table2 t2
on 1 = 0;
This will give you the columns in both tables. Each row will be populated with values from only one of the tables.
Similar to Gordons answer but the use of stars in SQL is one of the biggest NO NO's there is.
Also for the actual join part itself you need to do tablename.column = tablename.column on the unique columns. 1 = 0 is a bit ambiguous. but you get the picture
Use the below query join those two tables.
I think you wish to combine the values of two [(ItemNo and Item) and (Desc and M_Desc)] columns in same column and all the other columns separately.
SELECT CAST(ItemNo AS VARCHAR(MAX)) AS ItemNo, CAST(Desc AS VARCHAR(MAX)) AS Desc, OrderNumber, Qty,
S_Date, Location, NULL AS M_Date, NULL AS Total
FROM Table1
UNION ALL
SELECT CAST(Item AS VARCHAR(MAX)) AS ItemNo, CAST(M_Order AS VARCHAR(MAX)) AS Desc, NULL AS OrderNumber, NULL AS Qty,
NULL AS S_Date, NULL AS Location, M_Date, Total
FROM Table2

Simply by the Query

Table name is group. Column name is groupno,name,grouprefno,detail,undergroupno
Sample data of group
groupno name grouprefno detail undergroupno
1 A 001 abc 0
2 B 002 cde 0
3 AA 001001 abc 1
4 AC 001002 abc 1
5 AAA 001001001 DDD 3
6 DDD 001001002 ddd 3
7 www 001002001 223 4
8 eee 001002002 222 4
Now i want to get rows which name's are AA, AC and which are comes under the AA,AC
So i tried like this
select no from group where substring(grouprefno,1,
(select length(grouprefno) from group where name ='AA'
))=(select grouprefno from group
where name ='AA' ) union all select no from group where substring(grouprefno,1,
(select length(grouprefno) from group where name ='AC'
))=(select grouprefno from group
where groupname ='AC' )
Its Work Fine, But i want another solution because it has 2 sub query's in side of single query. It has any other feasible solution?
Am using postgresql 9.1
Try:
WITH q AS(
SELECT *
FROM Table1
WHERE name IN ('AA','AC')
)
SELECT * FROM q
UNION ALL
SELECT * FROM Table1 t
WHERE t.undergroupno IN (
SELECT groupno FROM q
)
Demo: http://sqlfiddle.com/#!12/fce65/3