This question already has answers here:
Pivot / Crosstab Query in Oracle 10g (Dynamic column number)
(2 answers)
Closed 8 years ago.
I have a query regarding pivoting a table with the following structure and data
Structure
Column Name Data Type
EMP_NAME VARCHAR2(30)
DT NUMBER(2,0)
PRESENT VARCHAR2(1)
EMP_NAME DT PRESENT
V 1 Y
V 2 Y
V 3 Y
V 4 Y
R 1 N
R 2 Y
R 3 Y
R 4 N
K 1 Y
K 2 Y
K 3 Y
K 4 N
I would like to pivot this table to display the name on the left , date on the top and the present in the centre (more like an attendance sheet). I got a code off the internet but that dint really help me. Please help..
Expected Output::
Name 1 2 3 4 5 6 7 8 9 10 11 12.......
R y y n y ......
V n y y n ......
K y y y y ....
The number of names can grow and the data range for dt column will be from 1-31.
Thanks in advance
Vivek
Here is the solution, but you need to know the number of values beforehand.
The assumption here is that 'Y' > 'N'.
Also note, that if in fact table some value is missing, like there is no record for some date then MAX function will return null. You should then surround it with NVL clause.
select EMP_NAME
,max(a1) as a1
,max(a2) as a2
,max(a3) as a3
...
from (select EMP_NAME
,decode(DT, '1', Present) as a1
,decode(DT, '2', Present) as a2
,decode(DT, '3', Present) as a3
...
from test)
group by EMP_NAME
order by EMP_NAME;
Related
I have table A, below, where for each unique id, there are two codes with some value.
Name Value
1 x
2 y
3 z
I want B, with format as below:
x y z
1 2 3
I am having an issue to make an update query making the update based on values other table. The problem is also that the other table has a To Many relation with the one I try to update.
Table A
ID isTrue hasOption1 hasOption2 hasOption3
1
2
3
4
5
6
7
Table B
ID OptionType
1 type1
1 type2
2 type2
1 type3
2 type1
6 type3
The Update needs to set in table A whether the ID has Any option, and set Y or N for the optionTypes like the below;
Table A after update:
ID isTrue hasOption1 hasOption2 hasOption3
1 Y Y Y Y
2 Y Y Y N
3 N N N N
4 N N N N
5 N N N N
6 Y N N Y
7 N N N N
It is probably a matter of syntax which I don't know for example how to make Update with a Join. Or would it be simpler to do several queries in VBA?
This Query is for Sql Server same will also work in MS Access.
update TableA set isTrue= case when (B.OptionType='type1') then 'Y' else 'N' end,
hasOption1=case when (B.OptionType='type2') then 'Y' else 'N' end,
hasOption2=case when (B.OptionType='type3') then 'Y' else 'N' end,
hasOption3=case when (B.OptionType='type4') then 'Y' else 'N' end from TableA AS A inner join tableb As B on A.ID=B.ID
Here's the sample:
select * from tmp
--output
A B Value
---------------------
a x 1
b x 2
a y 3
b y 4
c y 5
After a SQL command grouping on B column, I'd like to make each value of column A to be a separate column as illustrated below:
B a b c
----------------------------
x 1 2 null
y 3 4 5
If there any specific terminology for this transformation? Thanks!
You need to find max of other value and group it by with anchor column(b in your case). Please note that your column count should be similar to number of values expected in field A.
select b,
max(case when A='a' then Value else null end)a,
max(case when A='b' then Value else null end)b,
max(case when A='c' then Value else null end)c
from tmp
group by 1
Added more information to clear up some confusions. Thanks.
I am trying to group sets of values in SQL. I have the following table and trying to somehow get the results as shown in the following table. I have explored group sets in SQL 2008, cubes, basic group by clauses, but I am not able to figure out the SQL query. Can someone please help. You can change the end resultant table format if you want but the basic idea is about how to count similar sets of values. In this table a,b,c exists 2 times so the count is 2 and x,y exists 3 times so the count is 3 and x, y, z exists 1 time so the count is 1. Please help.
UserId ProductId
1 a
1 b
1 c
2 x
2 y
3 x
3 y
4 x
4 y
5 a
5 b
5 c
6 x
6 y
6 z
ProductId Count
a 2
b 2
c 2
x 3
y 3
x 1
y 1
z 1
SELECT COUNT(`ProductId`),`ProductId ` WHERE 1 GROUP BY `ProductId` ORDER BY `ProductId` ASC
SELECT ProductId, COUNT(UserId) AS NbrOfUsers
FROM TABLE_NAME
GROUP BY ProductId, COUNT(UserId)
You're selecting ProductId & the count of how many UserId exist for that ProductId.
GROUP BY ProductId will group your counted UserId based on ProductId and also display the count as NbrOfUsers.
Your output will look like this:
ProductId NbrOfUsers
a 2
b 2
c 2
x 3
y 3
I have a table like this.
ID NAME VALUE
______________
1 A X
2 A Y
3 A Z
4 B X
5 B Y
6 C X
7 C Z
8 D Z
9 E X
And the query:
SELECT * FROM TABLE1 T WHERE T.VALUE IN (X,Z)
This query gives me
ID NAME VALUE
______________
1 A X
3 A Z
4 B X
6 C X
7 C Z
8 D Z
9 E X
But i want to see all values of names which have all params. So, only A and C have both X and Z values, and my desired result is:
ID NAME VALUE
______________
1 A X
2 A Y
3 A Z
6 C X
7 C Z
How can I get the desired result? No matter with sql or with reporting service. Maybe "GROUP BY ..... HAVING" clause will help, but I'm not sure.
By the way I dont know how many params will be in the list.
I realy appreciate any help.
The standard approach would be something like
SELECT id, name, value
FROM table1 a
WHERE name IN (SELECT name
FROM table1 b
WHERE b.value in (x,y)
GROUP BY name
HAVING COUNT(distinct value) = 2)
That would require that you determine how many values are in the list so that you can use a 2 in the HAVING clause if there are 2 elements, a 5 if there are 5 elements, etc. You could also use analytic functions
SELECT id, name, value
FROM (SELECT id,
name,
value,
count(distinct value) over (partition by name) cnt
FROM table1 t1
WHERE t1.value in (x,y))
WHERE cnt = 2
I prefer to structure these "sets within sets" of queries as an aggregatino. I find this is the most flexible approach:
select t.*
from t
where t.name in (select name
from t
group by name
having sum(case when value = 'X' then 1 else 0 end) > 0 and
sum9case when value = 'Y' then 1 else 0 end) > 0
)
The subquery for the in finds all names that have at least one X value and one Y value. Using the same logic, it is easy to adjust for other conditions (X and Y and Z,; X and Y but not Z and so on). The outer query just returns all the rows instead of the names.