How does TRANSFORM PIVOT works - sql

TRANSFORM NbTest SELECT NbTest
FROM TableTest
WHERE Date=#25/10/2021#
GROUP BY Name
PIVOT Name
The above query give as output:
Expr1002 T1 T2 T3 T4 T5
2 2
1 1
0 0
2 2
3 3
How can I do to get it on one single line :
Expr1002 T1 T2 T3 T4 T5
Result = 2 1 0 2 3

You should list TableTest, as Gustav indicates, and we can then provide better feedback. With the information you provide, I guess that what you want is:
TRANSFORM First(NbTest)
SELECT "Result="
FROM TableTest
WHERE Date=#25/10/2021#
GROUP BY True
PIVOT Name ;
Notice that this makes sense if for "Date=#25/10/2021#", and for each distinct value of "Name", you only have one value of "NbTest". If for "Date=#25/10/2021#", and for each distinct value of "Name", you have several values of "NbTest", using "First()" will basically produce a random one: in this case may be you prefer to use "Max()" or "Min()" or some other of the available SQL aggregate functions.

Related

result table description

I want to write a query in SQL. Can someone help me for writing oracle sql query for below result table
Table 1 Data
prodno description
1 Laptop
2 Charger
3 Mouse
Table 2 Data
prodno prodset_no
1 1
2 1
3 1
1 2
3 2
1 3
2 3
Result Table
prodset_no prodset_desc
1 Laptop,Charger,Mouse
2 Laptop,Mouse
3 Laptop,Charger
JOIN the two table and then use listagg to produce comma separated output:
select t2.prodset_no,
listagg(t1.description, ',') within group (
order by t1.prodno
) prodset_desc
from table2 t2
join table1 t1 on t2.prodno = t1.prodno
group by t2.prodset_no;
Also, worth a note that the listagg has a limit of 4000 bytes. If you hit that limit, you can either use XMLAGG or rethink the problem and not do it in SQL at all but rather handle it in your application code.

Apply a Substr to a distinct result in oracle

In Oracle, I need to do the average of a column (timeInmillis) from a join query that shows "duplicated" values (relative to the timeInmillis column from table1). I need to mantain the values from the join, but get the right result for the average.
I'm trying to do something like this:
select AVG(SUBSTR(DISTINCT(concat(id1,timeInMillis)),LENGTH(id1)+1,LENGTH(CONCAT(id1,timeInMillis)))), someColumn, otherColumn
FROM table1 t1
LEFT JOIN table2 t2 ON t1.id1 = t2.id1 group by somestuff,someotherStuff;
If I try to do this, I get:
ORA-00936: missing expression
This would be an example:
Table1:
id1 timeInMillis otherColumn
1 5 X
2 15 X
Table2:
id2 id1 otherColumn
--------------------
1 1 X
2 1 X
3 2 X
From my join I get a resultset like this:
id1 id2 timeInmillis moreColumns
--------------------------------
1 1 5 X
1 2 5 X
2 3 15 X
I need to get the average of 5 and 15 (with distinct id1), but I can't modify the where part of the sql (cause of the other values I'm getting)
My result should be:
AVG(TIMEINMILLIS) otherResults
----------------------------------
10 'whatever'
Thanks in advance.
1) Option
select SUBSTR(someColumn,n,m) from (
select DISTINCT someColumn from MYTABLE
);
2) Option
select DISTINCT SUBSTR(someColumn,n,m) from MYTABLE;
*) Queries can return different result.
Your last edit finally explains clearly what you want. You want one line only, showing the avarage of table1's values, but of course without the duplicates that you got because of joining with table 2.
One solution is to get to the final value in two steps:
select avg(distinct_time), sum(sub_sum)
from
(
select max(timeinmillis) as distinct_time, sum(some_other_colum) as sub_sum
from (query)
group by id1
);
The other solution would be to rewrite the query.
Your syntax is wrong. You can try somthing like this either:-
select avg(TimeInMillis), other_cols_as_well
from(SELECT TAB1.id1, TAB2.id2, avg(TimeInMillis) as TimeInMillis
FROM TAB1, TAB2
WHERE TAB1.id1 = TAB2.id1
group by TAB1.id1, TAB2.id2) temp
where temp.id1 <> temp.id2
group by other_cols_as_well
Here is the fiddle
http://sqlfiddle.com/#!4/1fc017/16

SQL return a default value if a row is not found [PostgreSQL]

I'm wondering if it was doable (in one query if possible) to make the query return a default value if a row is missing ? For example takes these 2 tables and given my query takes 2 parameter (place_id and user_id)
T1
place_id / tag_id
1 2
1 3
1 4
2 4
3 2
4 5
T2
user_id / tag_id / count
100 2 1
100 3 20
200 4 30
200 2 2
300 5 22
As you see, the pair user/tag (100,4) is missing. What I would like to archive is a query that will return me these 3 results
tag_id / count
2 1
3 20
4 0
I know that i can do this with something like this but it doesn't really match the final result as it only works if i know in advance the tag_id... and obviously only return 1 row..:
SELECT T1.tag_id, T2.count
from T1 t1
left join T2 t2 on t1.tagId=t2.tag_id
where t1.place_id=1
UNION ALL
select tag_id,0
from T1
where not exist (select 1 from T2 where user_id=100 and tag_id=4)
and tag_id=4;
EDIT: My question was not complete and had missing cases
here is an example (curtesy of #a_horse_with_no_name) http://sqlfiddle.com/#!12/67042/4
Thank you!
The outer join will already take care of what you want.
As t1 is the "left table" of the join, all rows from t1 will be returned. Columns from the "right table" (t2 in your example) will then have a null value. So you only need to convert that null to a 0:
select t1.tag_id, coalesce(t2.cnt, 0)
from T1 t1
left join T2 t2 on t1.tag_Id=t2.tag_id
and t1.place_id = 1;
SQLFiddle example: http://sqlfiddle.com/#!12/ed7bf/1
Unrelated but:
Using count as a column name is a really bad idea, because it will require you to always enclose the column name in double quotes: t2."count" because it is a reserved word. Plus it doesn't really document the purpose of the column. You should find a better name for that.

Summing a column up to a certain row (using GROUP BY and OVER)?

I have a table that lists the duration of different activities. It looks like
id duration
1 15
2 30
3 30
4 45
5 30
...etc
I want to sum these activities like
for (lastActivity=1 to 5)
SELECT id, SUM(duration) FROM durations
WHERE id<=lastActivity
to produce an output like
id endtime
1 15
2 45
3 75
4 120
5 150
where each row sums the duration of the activities up to its position in the list.
It seems an easy task (and possibly is), but I can't figure out how the sql should look like to produce such an output. I have tried using GROUP BY together with the OVER clause but perhaps there's a simpler way of doing this.
SELECT t.id,
t.duration,
rt.runningTotal
FROM mytable t
CROSS apply (SELECT Sum(duration) AS runningTotal
FROM emp
WHERE id <= t.id) AS rt
ORDER BY t.id
The APPLY operator allows you to invoke a table-valued function for each row returned by an outer table expression of a query. The table-valued function acts as the right input and the outer table expression acts as the left input. The right input is evaluated for each row from the left input and the rows produced are combined for the final output. The list of columns produced by the APPLY operator is the set of columns in the left input followed by the list of columns returned by the right input.
Note : To use APPLY, the database compatibility level must be at least 90. This was introduced in sql server 2005.
you can use running total
check this post
Running total in sqlserver stackoverflow
This will degrade depending on how large your actual table is, but this should do the trick:
Some interesting reading around this can be found here
SELECT 1 as id, 15 as num into #test
UNION ALL SELECT 2, 30
UNION ALL SELECT 3, 30
UNION ALL SELECT 4, 45
UNION ALL SELECT 5, 30
select
t1.id
,MAX(t1.num) as id_num
,SUM(t2.num) as running_total
from #test t1
LEFT OUTER JOIN #test t2 on t2.id <= t1.id
GROUP BY
t1.id
Try this :
select d2.ID,sum(d1.duration)
from durations d1,durations d2
where d1.id<=d2.id
group by d2.id

Add Column values in sql server query

I have result of two queries like:
Result of query 1
ID Value
1 4
2 0
3 6
4 9
Result of query 2
ID Value
1 6
2 4
3 0
4 1
I want to add values column "Value" and show final result:
Result of Both queries
ID Value
1 10
2 4
3 6
4 10
plz guide me...
select id, sum(value) as value
from (
select id, value from query1
uninon all
select id, value from query2
) x
group by id
Try using a JOIN:
SELECT
T1.ID,
T1.Value + T2.Value AS Value
FROM (...query1...) AS T1
JOIN (...query2...) AS T2
ON T1.Id = T2.Id
You may also need to consider what should happen if there is an Id present in one result but not in the other. The current query will omit it from the results. You may want to investigate OUTER JOIN as an alternative.
A not particularly nice but fairly easy to comprehend way would be:
SELECT ID,SUM(Value) FROM
(
(SELECT IDColumn AS ID,ValueColumn AS Value FROM TableA) t1
OUTER JOIN
(SELECT IDColumn AS ID,ValueColumn AS Value FROM TableB) t2
) a GROUP BY a.ID
It has the benefits of
a) I don't know your actual table structure so you should be able to work out how to get the two 'SELECT's working from your original queries
b) If ID doesn't appear in either table, that's fine