I want to perform SUM with UNION operation. But there is an error.
SELECT x.YEAR_WISE,x.OFFICE_NAME,x.CATEGORY,x.KWT_COUNT,x.NON_KWT_COUNT FROM x
UNION ALL
SELECT ''AS YEAR_WISE,'' AS OFFICE_NAME,'SUM',sum(x.KWT_COUNT),sum(x.NON_KWT_COUNT)FROM x;
Here x is created using WITH command [with x as(select * from ..)]
The output in x is as follows:
YEAR_WISE OFFICE_NAME CATEGORY KWT_COUNT NON_KWT_COUNT
2,019 HeadQuarters-MultiSpeciality Doctor 18 40
2,019 HeadQuarters-MultiSpeciality Nurse 7 16
On performing UNION and SUM the output that is required is as follows:
YEAR_WISE OFFICE_NAME CATEGORY KWT_COUNT NON_KWT_COUNT
2,019 HeadQuarters-MultiSpeciality Doctor 18 40
2,019 HeadQuarters-MultiSpeciality Nurse 7 16
SUM 25 56
How to achieve this output? What is the modification required in query?
Note that I don't want subquery, I want TOTAL SUM at bottom.
Try this:
SELECT x.YEAR_WISE
,x.OFFICE_NAME
,x.CATEGORY
,sum(x.KWT_COUNT)
,sum(x.NON_KWT_COUNT)
FROM x
GROUP BY GROUPING SETS
(
(x.YEAR_WISE,x.OFFICE_NAME,x.CATEGORY)
,()
)
you can find more info about grouping sets here.
Related
The task is the following: select 20 rows from dual table with randomly generated distinct numbers from 23 to 45.
I performed the following:
select distinct floor(dbms_random.value(23,45)) output
from dual
connect by rownum <= 20;
But it selects random number of rows less than 20. For example:
OUTPUT
44
35
25
27
40
32
26
36
43
34
31
33
37
13 rows selected.
Please help, how to select exactly 20 numbers, not less? Lot of thanks in advance!
Use a row generator to generate all the numbers; order them randomly using DBMS_RANDOM.VALUE and then get the first 20 rows:
SELECT OUTPUT
FROM (
SELECT 22 + LEVEL AS OUTPUT
FROM DUAL
CONNECT BY 22 + LEVEL <= 45
ORDER BY DBMS_RANDOM.VALUE
)
WHERE ROWNUM <= 20
Why your code does not work:
The code you are using may randomly generate 20 distinct numbers but it is highly likely that it will not as it will generate 20 rows of random integers between 23 and 45 and then the DISTINCT clause will remove all the duplicates and you are likely to have duplicates which will reduce the final number of rows below 20.
Mathematically, the first row it generates will be unique then there is a 22-in-23 chance the second row is unique and, given the previous rows are unique, a 21-in-23 chance the 3rd row is unique and ... a 4-in-23 chance the 20th row is unique. Multiplying all those probabilities together:
SELECT probabilities ( number_of_rows, probability ) AS (
SELECT 1, 1 FROM DUAL
UNION ALL
SELECT number_of_rows + 1, probability * ( 23 - number_of_rows ) / 23
FROM probabilities
WHERE number_of_rows < 20
)
SELECT * FROM probabilities;
Gives a probability of 0.0000025 that you will generate all 20 rows with your method - possible but improbable.
I have a table as UserData which has strucure like
id category value
1 AR 100
2 WT 90
3 WT 12
4 AR 1000
5 AR 2005
6 WT 122
7 BP 112
8 BP 18
now I want to select all rows which has maximum value in the indiviual category. so my result set should be.
id category value
5 AR 2005
6 WT 122
7 BP 112
I want to have this in both MongoDB and SQL server query.
In SQL I tried this
select id,category,value from
(select id,
category,
value,
max(value)
over (partition by category) result
from UserData ) a
where a.result=a.value order by a.id
this is giving me desired result but somehow I feel that it is not good
so I want a better solution for this in SQL and corresponding equivalent solution for MongoDB
I'm not sure about a mongo solution, but if you don't care about Id - here is the way to get the highest value for a category.
SELECT DISTINCT
Category, MAX(Value)
FROM UserData
GROUP BY category
Excuse me if this is more simplistic than what you desire.
I have a table which Data is like
LayerID Company id Company name Layer Name Price
1 1 x x1 20
2 1 x x2 10
3 2 y y1 50
4 2 y y2 50
5 2 y y3 50
6 3 z z1 15
What I want is to have the following table after SQL query is applied
Company id Company name Price
1 x 30
2 y 50
3 z 15
i.e. the following rules apply:
if the price for the different layers for the company are different then sum them up
example: for company x it would be 20+10 = 30
if the price for the different layers for the company are the same then take that number
example: for company y it would be 50, for z it would be 15
I'm not sure how i would so this in SQL (for Access/VBA), and have been trying to figure this out to no avail.
Thanks for your help in advance
Claudy
The SQL query that would produce the result you are looking for:
SELECT m.Company_id, m.Company_name, SUM(m.Price)
FROM
(
SELECT DISTINCT Company_id, Company_name, Price
FROM MyTable
) AS m
GROUP BY m.Company_id, m.Company_name
You can do this as:
SELECT m.Company_id, m.Company_name, SUM(distinct m.Price)
FROM table m
GROUP BY m.Company_id, m.Company_name;
As a warning: I never use sum(distinct). It generally indicates an error in the underlying data structure or subquery generating the data.
EDIT:
Why is it bad to do this? Generally, what you really want is:
SUM(m.Price) where <some id> is distinct
But you can't phrase that in SQL without a subquery. If the above is what you want, then you have a problem when two "id"s have the same price. The sum() produces the wrong value.
I have the following query to count how many times each process_track_id occurs in a table:
SELECT
a.process_track_id,
COUNT(1) AS 'num'
FROM
transreport.process_name a
GROUP BY
a.process_track_id
This returns the following results:
process_track_id | num
1 14
2 44
3 16
5 8
6 18
7 17
8 14
This is great. Now is the part where I am stuck. I would like to get the following table:
num count
8 1
14 2
16 1
17 1
18 1
44 1
Where num are the distinct counts from the first table, and count is how many times that frequency occurs.
Here is what I have tried (it's a subquery, but I'm not sold on the method) and I haven't been able to get it to work just yet. I'm new to SQL and I think I'm missing out on some some key aspects of the syntax.
SELECT
X.id_count,
count(1) as 'num_count'
FROM
(SELECT
a.process_track_id,
COUNT(1) AS 'id_count'
FROM
transreport.process_name a
GROUP BY
a.process_track_id
--COUNT(1) AS 'id_count'
) X;
Any ideas?
It's probably good to keep in mind that this may have to be run on a database with at least 1 million records, and I don't have the ability to create a new table in the process.
Thanks!
Here's the subquery method you were driving at:
SELECT id_count, COUNT(*) AS 'num_count'
FROM (SELECT a.process_track_id
,COUNT(*) AS 'id_count'
FROM transreport.process_name a
GROUP BY a.process_track_id
)sub
GROUP BY id_count
Not sure there's a better method as the aggregation needs to run once anyway.
Try this
SELECT x.num, COUNT(*) AS COUNT
FROM (
SELECT
a.process_track_id, -- <--- You may removed this column
COUNT(*) AS 'num'
FROM
transreport.process_name a
GROUP BY
a.process_track_id
) X
GROUP BY X.num
I have a sql / sqlite question. I need to write a query that select some values from a sqlite database table. I always want the maximal returned records to be 20. If the total selected records are more than 20 I need to select 20 records that are spread evenly (no random) over the total records. It is also important that I always select the first and last value from the table when sorted on the date. These records should be inserted first and last in the result.
I know how to accomplish this in code but it would be perfect to have a sqlite query that can do the same.
The query Im using now is really simple and looks like this:
"SELECT value,date,valueid FROM tblvalue WHERE tblvalue.deleted=0 ORDER BY DATE(date)"
If I for example have these records in the talbe and to make an easier example the maximum result I want is 5.
id value date
1 10 2010-04-10
2 8 2010-04-11
3 8 2010-04-13
4 9 2010-04-15
5 10 2010-04-16
6 9 2010-04-17
7 8 2010-04-18
8 11 2010-04-19
9 9 2010-04-20
10 10 2010-04-24
The result I would like is spread evenly like this:
id value date
1 10 2010-04-10
3 8 2010-04-13
5 10 2010-04-16
7 8 2010-04-18
10 10 2010-04-24
Hope that explain what I want, thanks!
Something like this should work for you:
SELECT *
FROM (
SELECT v.value, v.date, v.valueid
FROM tblvalue v
LEFT OUTER JOIN (
SELECT min(DATE(date)) as MinDate, max(DATE(date)) as MaxDate
FROM tblvalue
WHERE tblvalue.deleted = 0
) vm on DATE(v.date) = vm.MinDate or DATE(v.date) = vm.MaxDate
WHERE tblvalue.deleted = 0
ORDER BY vm.MinDate desc, Random()
LIMIT 20
) a
ORDER BY DATE(date)
I think you want this:
SELECT value,date,valueid FROM tblvalue WHERE tblvalue.deleted=0
ORDER BY DATE(date), Random()
LIMIT 20
In other words you want select rows with date column, so that date is from the sorted list of dates, from where we take every odd element? And add the last recorded element (with the latest date)? And everything limited to max 20 rows?
If that's the case, then I think this one should do:
SELECT id,value,date FROM source_table WHERE date IN (SELECT date FROM source_table WHERE (rowid-1) % 2 = 0 OR date = (SELECT max(date) FROM source_table) ORDER BY date) LIMIT 20