Query a table so that data in one column could be shown as different fields - sql

I have a table that stores data of customer care . The table/view has the following structure.
userid calls_received calls_answered calls_rejected call_date
-----------------------------------------------------------------------
1030 134 100 34 28-05-2018
1012 140 120 20 28-05-2018
1045 120 80 40 28-05-2018
1030 99 39 50 28-04-2018
1045 50 30 20 28-04-2018
1045 200 100 100 28-05-2017
1030 160 90 70 28-04-2017
1045 50 30 20 28-04-2017
This is the sample data. The data is stored on day basis.
I have to create a report in a report designer software that takes date as an input. When user selects a date for eg. 28/05/2018. This date is send as parameter ${call_date}. i have to query the view in such a way that result should look like as below. If user selects date 28/05/2018 then data of 28/04/2018 and 28/05/2017 should be displayed side by side as like the below column order.
userid | cl_cur | ans_cur | rej_cur |success_percentage |diff_percent|position_last_month| cl_last_mon | ans_las_mon | rej_last_mon |percentage_lm|cl_last_year | ans_last_year | rej_last_year
1030 | 134 | 100 | 34 | 74.6 % | 14% | 2 | 99 | 39 | 50 | 39.3% | 160 | 90 | 70
1045 | 120 | 80 | 40 | 66.6% | 26.7% | 1 | 50 | 30 | 20 | 60% | 50 | 30 | 20
The objective of this query is to show data of selected day, data of same day previous month and same day previous years in columns so that user can have a look and compare. Here the result is ordered by percentage(ans_cur/cl_cur) of selected day in descending order of calculated percentage and show under success_percentage.
The column position_last_month is the position of that particular employee in previous month when it is ordered in descending order of percentage. In this example userid 1030 was in 2nd position last month and userid 1045 in 1 st position last month. Similarly I have to calculate this also for year.
Also there is a field called diff_percent which calculates the difference of percentage between the person who where in same position last month.Same i have to do for last year. How i can achieve this result.Please help.

THIS ANSWERS THE ORIGINAL VERSION OF THE QUESTION.
One method is a join:
select t.user_id,
t.calls_received as cr_cur, t.calls_answered as ca_cur, t.calls_rejected as cr_cur,
tm.calls_received as cr_last_mon, tm.calls_answered as ca_last_mon, tm.calls_rejected as cr_last_mon,
ty.calls_received as cr_last_year, ty.calls_answered as ca_last_year, ty.calls_rejected as cr_last_year
from t left join
t tm
on tm.userid = t.userid and
tm.call_date = dateadd(month, -1, t.call_date) left join
t ty
on ty.userid = t.userid and
tm.call_date = dateadd(year, -1, t.call_date)
where t.call_date = ${call_date};

Related

Query returns a few extra records

I have these tables and this query in an Access database:
samples
hole_id | depth_from | depth_to |
DH001 100 105
DH001 105 120
DH001 110 115
DH001 115 120
overlapping_samples (and therefore the correct output)
hole_id | depth_from | depth_to |
DH001 110 115
DH001 115 120
query
SELECT a.*
FROM samples AS a
INNER JOIN overlapping_samples AS o
ON a.hole_id=o.hole_id
WHERE a.hole_id=o.hole_id AND a.depth_to=o.depth_to
;
results
hole_id | depth_from | depth_to |
DH001 100 105
DH001 110 115
DH001 115 120
It's very simple. The result is almost ok, but it includes some extra records from the left table (i.e. samples). In fact, in the example above it may not necessarily return the extra row. Only a small percentage are.
If not obvious, I want to return all the records from the left table that match to the right table. The right table is actually a subset of the left, and therefore the query should have the same number of records. It's intended for a DELETE statement, but
i've changed your query to:
SELECT a.hole_id as ahole_id, a.depth_from as adepth_from, a.depth_to as adepth_to,o.hole_id as ohole_id, o.depth_from as odepth_from, o.depth_to as odepth_to
FROM samples AS a
LEFT JOIN overlapping_samples AS o ON a.hole_id=o.hole_id AND a.depth_to=o.depth_to AND a.depth_from=o.depth_from
WHERE a.hole_id=o.hole_id AND a.depth_to=o.depth_to;
and it gave me this result
ahole_id | adepth_from | adepth_to | ohole_id | odepth_from | odepth_to |
DH001 110 115 DH001 110 115
DH001 115 120 DH001 115 120
is that what you were looking for?
this may work:
SELECT a.*
FROM samples a
JOIN overlapping_samples o ON a.hole_id = o.hole_id
WHERE a.depth_from = o.depth_from
AND a.depth_to = o.depth_to;
I fixed a problem in WHERE clause, from:
a.hole_id=o.hole_id
to:
a.depth_from = o.depth_from
hole_id is already present in JOIN ... ON a.hole_id = o.hole_id
if you still don't get correct count you may need to look at your data and add some extra condition either in WHERE or JOIN clause

select from table with between

please, help advice.
I have a table.
id|score_max|score_min| segment
--|---------|---------|--------
1 |264 | |girl
2 |263 | 250 |girl+
3 |249 | 240 |girl
4 | | 239 |girl
It is not necessary to obtain a value depending on the value of the score.
But it can be null.
For example, 260 is value from other table
select segment
from mytable
where score_max<260 and score_min>260
Output:
2 |263 | 250 |girl+
but if value =200, sql is not correct
How to make a request correctly?
For this sample data that makes more sense:
id|score_max|score_min| segment
--|---------|---------|--------
1 | | 264 |girl
2 |263 | 250 |girl+
3 |249 | 240 |girl
4 |239 | |girl
you can get the result that you want like this:
select *
from tablename
where
(? >= score_min or score_min is null)
and
(? <= score_max or score_max is null)
Replace ? with the value that you search for.
See the demo.

PostgreSQL select only rows whose dates match a specific number of the week in a table

I have a table that looks like this for a span of many years:
dump_time | group_id | client_count
---------------------+----------+--------------
2014-10-21 19:45:00 | 145 | 74
2014-10-21 19:45:00 | 131 | 279
2014-10-21 19:45:00 | 139 | 49
where dump_time is of type 'timestamp without time zone'.
I want to select only rows that match a specific week of the year and a specific day of the week. For instance, I want all rows that are 3rd day of the 15th week of the year. Any idea on how I could do this? I've explored the EXTRACT command, but haven't quite figured it out.
Thanks!
select *
from testme
where extract(week from dump_time) = 15
and extract(dow from dump_time) = 3

Reordering groups within a categorical variable

I'm struggling to reorder the categories in an income group variable.
It is currently in alphabetical order but I wish to change it to be permanently in order of amount (so moving £100 000 and greater to the bottom)
Income Group | Freq. Percent Cum.
Under £20 000 | 11 9.73 9.73
£100 000 and greater | 7 6.19 15.93
£20 000 to 29 999 | 18 15.93 31.86
£30 000 to 49 999 | 38 33.63 65.49
£50 000 to 74 999 | 27 23.89 89.38
£75 000 to 99 999 | 12 10.62 100.00
Create a new variable and assign each of the categories a number. For example,
gen order = 1 if income=="Under £20 000"
replace order = 2 if income=="£20 000 to 29 999"
...
replace order = 6 if income=="£100 000 and greater"
sort order
drop order
If the income variable is numeric, rather than string, sub in the numeric values above.

sum revenue based on criteria form another table Powerpivot

I have a model where I have Revenue table that has revenue2016 column
another table Programs where i have
program | min
I would like to add a calculated column to programs table so that it sums revenue that is grater than the min like so
=CALCULATE(SUM(Revenue[revenue2016 ]),Revenue[revenue2016]>=Programs[min])
this gave me an error
The data should look like this
#Revenue
Revenue
10
10
10
10
10
100
100
100
100
100
1000
1000
1000
1000
1000
#Programs
program | min | summed rev
a | 10 | 5550
b | 100 | 5500
c | 1000 | 5000
Just After I posted it I found the answer, I'll share it if someone else came across same issue
=calculate(sum(Revenue[revenue2016]),filter(Revenue,Revenue[revenue2016]>=Programs[Min]))