It's a question I got this afternoon:
There a table contains ID, emp_Name,emp_mailid and Salary of Employees, get names of the first-highest salary employees, in oracle
here this is my table
id emp_name emp_mailid salary
2 dinesh dinesh#gmail.com 5000
3 ganesh ganesh#gmail.com 6000
6 ramesh ramesh#gmail.com 4500
10 suresh suresh#gmail.com 10000
11 rajesh rajesh#gmail.com 15000
15 kamesh kamesh#gmail.com 16000
16 kamalesh kamalesh#gmail.com 7800
19 neelash neelash#gmail.com 12563
20 rajan rajan#gmail.com 156231
22 vignesh vignesh#gmail.com 45220
30 rubesh rubesh#gmail.com 78000
31 john john#gmail.com 6522
and this my query:
select *
from
(
select
salary
,dense_rank() over (order by salary desc) ranking
from test
)
where ranking = 1
when i execute this it shows maximum salary as 78000 but actually its wrong maximum salary is 156231
Can you suggest me a better query?
If it shows you the maximum as 78000, it's probably because the salary column is varchar and not number.
try this:
select *
from
(
select
salary
,dense_rank() over (order by to_number(salary) desc) ranking
from test
)
where ranking = 1
Related
I have a sqlite database with this info
id
pcs
dollars
year
10
25
150
2021
10
20
160
2021
10
22
120
2022
11
12
130
2021
11
10
100
2022
I want to get this
id
pcs2021
dollars2021
pcs2022
dollars2022
10
45
310
22
120
11
12
130
10
100
I got this:
SELECT id, SUM(pcs), SUM(dollars) FROM Table GROUP BY id
But I can't find the way to get the SUM of each year separately.
I tried something like:
SELECT id, (SELECT SUM(pcs) FROM Table WHERE id=id AND year=2021) AS pcs2021, (SELECT SUM(dollars) FROM Table WHERE id=id AND year=2021) AS dollars2021, (SELECT SUM(pcs) FROM Table WHERE id=id AND year=2022) AS pcs2022, (SELECT SUM(dollars) FROM Table WHERE id=id AND year=2022) AS dollars2022, FROM Table GROUP BY id
but it doesn't work.....
Thank you for your help.
Using :-
SELECT id, SUM(pcs) AS pcs2021, SUM(dollars) AS dollars2021 FROM `Table` WHERE year = 2021 GROUP BY id;
results in :-
note the above assumes year is an integer so you may have to enclose the literal in single quotes.
Additional (re comment)
My problem is when I want to put different columns with SUM of values for each year
An issue you are having is that id=id will always be true and thus you will sum all rows, irrespective of the id, for the year and get the result (when the syntax is correct):-
That is id is the id of the sub query when you want to compare against the id currently being processed by the main query.
To do this you can give the main query an alias using the AS clause and then refer to the id of the alias so (where the main query is given the alias of a):-
SELECT
id,
(SELECT sum(pcs) FROM `table` WHERE id=a.id AND year='2021') AS pcs2021,
(SELECT sum(dollars) FROM `table` WHERE id=a.id AND year='2021') AS dollars2021,
(SELECT sum(pcs) FROM `table` WHERE id=a.id AND year='2022') AS pcs2022,
(SELECT sum(dollars) FROM `table` WHERE id=a.id AND year='2022') AS dollars2022
FROM `table` AS a
GROUP BY id
;
The result being :-
Note the use of Table as a table name will result in a syntax error if it is not enclosed as Table is an SQLite keyword.
I'm trying to create a metabase query, where I want to calculate the % of a particular feedback-label by total, grouped by start-batter
I count all columns by start-battery
I then join that count with the original data again, so each column has the total of that start battery.
I then count again by start-battery and feedback-label
SQL
SELECT
"source"."START_BATTERY" AS "START_BATTERY",
"source"."count" AS "count",
"Ride Dev"."FEEDBACK_TAGS_STRING" AS "FEEDBACK_TAGS_STRING",
COUNT(*) AS "count"
FROM
(SELECT
"MART"."CORE"."RIDE_DEV"."START_BATTERY" AS "START_BATTERY",
COUNT(*) AS "count"
FROM
"MART"."CORE"."RIDE_DEV"
WHERE
((NOT (LOWER("MART"."CORE"."RIDE_DEV"."FEEDBACK_TAGS_STRING") LIKE '%,%')
OR "MART"."CORE"."RIDE_DEV"."FEEDBACK_TAGS_STRING" IS NULL)
AND "MART"."CORE"."RIDE_DEV"."START_BATTERY" <= 100
AND "MART"."CORE"."RIDE_DEV"."START_BATTERY" > 20
AND "MART"."CORE"."RIDE_DEV"."FEEDBACK_TAGS" IS NOT NULL
AND "MART"."CORE"."RIDE_DEV"."VEHICLE_MODEL" = 'Voiager 3X (NB Max)')
GROUP BY
"MART"."CORE"."RIDE_DEV"."START_BATTERY"
ORDER BY
"MART"."CORE"."RIDE_DEV"."START_BATTERY" ASC) "source"
LEFT JOIN
"MART"."CORE"."RIDE_DEV" "Ride Dev" ON "source"."START_BATTERY" = "Ride Dev"."START_BATTERY"
WHERE
("Ride Dev"."FEEDBACK_TAGS_STRING" IS NOT NULL
AND ("Ride Dev"."FEEDBACK_TAGS_STRING" <> '' OR "Ride Dev"."FEEDBACK_TAGS_STRING" IS NULL)
AND (NOT (LOWER("Ride Dev"."FEEDBACK_TAGS_STRING") LIKE '%,%')
OR "Ride Dev"."FEEDBACK_TAGS_STRING" IS NULL))
GROUP BY
"source"."START_BATTERY", "source"."count",
"Ride Dev"."FEEDBACK_TAGS_STRING" ORDER BY "source"."START_BATTERY" ASC,
"source"."count" ASC, "Ride Dev"."FEEDBACK_TAGS_STRING" ASC
Result
Start Battery Count Ride Dev → Feedback Tags String Count
21 6598 couldnt_end_ride 916
21 6598 motor_didnt_start 2
21 6598 other 1
21 6598 scooter_didnt_start 1569
21 6598 slow 3667
21 6598 stopped_during_ride 3150
22 6815 couldnt_end_ride 866
22 6815 other 2
22 6815 scooter_didnt_start 1617
22 6815 screws_missing 1
Is it possible to name the counted columns so they are easier to keep apart?
I'd like to create a calculated field with count / Ride Dev → Count I click summarize and add custom field [Ride Dev.coun] / [Count] but it doesn't recognize the first field. How can I reference the first field?
Below is the link of my previous quetsion.
Retain values till there is a change in value in Teradata
It worked as suggested by one of the community members #Dnoeth. Can this retention be done only for certain section of data?
I.e, Retain data only for data where Dep is A or B . When Dep is C just use same value as input and no need to retain till certain value.
Data:
Cust_id Balance st_ts Dep
123 1000 27MAY2018 A
123 350 31MAY2018 A
256 2000 29MAY2018 B
345 1000 28APR2018 C
345 1200 26MAY2018 C
Output reqd:
Cust_id Balance st_ts Dep
123 1000 27MAY2018 A
123 1000 28MAY2018 A
123 1000 29MAY2018 A
123 1000 30MAY2018 A
123 350 31MAY2018 A
256 2000 29MAY2018 B
256 2000 30MAY2018 B
256 2000 31MAY2018 B
345 1000 28APR2018 C
345 1200 26MAY2018 C
Query used:
Wth cte
{
SELECT customer_id, bal, st_ts,
-- return the next row's date
Coalesce(Min(st_ts)
Over (PARTITION BY customer_id
ORDER BY st_ts
ROWS BETWEEN 1 Following AND 1 Following)
,Date '2018-06-01') AS next_Txn_dt
FROM BAL_DET;
}
SELECT customer_id, bal
,Last(pd) -- last day of the period
FROM cTE
-- make a period of the current and next row's date
-- and return one row per day
EXPAND ON PERIOD(ST_TS, next_Txn_dt) AS pd;
Thanks
Sandy
You can add a CASE to check for Dep = 'C':
WITH cte AS
( SELECT customer_id, bal, st_ts, dep,
-- return the next row's date
CASE
WHEN dep = 'C'
THEN st_ts +1 -- simply increase date
ELSE
Coalesce(Min(st_ts)
Over (PARTITION BY customer_id
ORDER BY st_ts
ROWS BETWEEN 1 Following AND 1 Following)
,DATE '2018-06-01')
END AS next_Txn_dt
FROM BAL_DET
)
SELECT customer_id, bal
,Last(pd) -- last day of the period
,dep
FROM cTE
-- make a period of the current and next row's date
-- and return one row per day
EXPAND ON PERIOD(ST_TS, next_Txn_dt) AS pd
I have a sample table with following values
SNO | Mon
-----+-------
100 | 1
101 | 1
102 | 1
100 | 2
101 | 2
102 | 2
100 | 3
101 | 3
Now I need a query to count the total sno's which are in 3 months
The result should be 2, as 100 & 101 are in mon 1,2 and 3. However, 102 is only present in mon 1,2.
Thanks,
RK
This Query in theory should work.
SELECT
tmpTbl.sNo
FROM
tmpTbl
GROUP BY
tmpTbl.sNo
HAVING
Count(tmpTbl.monNo) = (SELECT Count(*) FROM (SELECT tmpTbl.monNo FROM tmpTbl GROUP BY tmpTbl.monNo));
The result would be,
sNo
----
100
101
I have used two SubQueries to get the result. Teh both are used in the HAVING clause of the SQL. First SqubQuery (inner most). Will get the number of Unique Month's available in your table, the outer SubQuery will then Count the number of Unique months. So the Overall Query can be translated as "SELECT the serial number FROM the table HAVING the Count of Month equal to the Number of unique records in the same table".
The reason I used SbQuery instead of a number is because of the fact this will also be applicable when your month number increases. Hope this helps !
EDIT
Here is the Query for getting the count.
SELECT
Count(*) As simpleCount
FROM
(
SELECT
tmpTbl.sNo
FROM
tmpTbl
GROUP BY
tmpTbl.sNo
HAVING
Count(tmpTbl.monNo) = (SELECT Count(*) FROM (SELECT tmpTbl.monNo FROM tmpTbl GROUP BY tmpTbl.monNo))
);
my tables
DESC emp
Name Null Type
------------------------------ -------- --------------------------
EMP_NO NUMBER
EMP_NAME VARCHAR2(10)
ADDRESS VARCHAR2(15)
PH_NO NUMBER(10)
DEPT_NO NUMBER
result:
1 ram ctr 8892939927 100
2 mohan ptr 7569936347 101
3 mallu ppt 9553438342 102
4 scoot dmc 9874563210 103
5 jim plr 9236548875 104
6 ravi tpt 8562398756 105
7 manju hyd 7562398742 106
8 manoj hyd 869523654 107
9 sarath ctr 9632158769 108
10 hemanth mpk 9632147852 109
desc salary
Name Null Type
------------------------------ -------- --------------------------
EMP_NO NUMBER
SALARY NUMBER(10)
PERIOD VARCHAR2(10)
START_DATE DATE
END_DATE DATE
result:
1 12580 15months 12-DEC-07 10-DEC-10
2 15500 19months 10-JAN-07 10-DEC-11
3 7777 18months 11-JUL-07 21-APR-11
4 9999 11months 07-JUL-07 31-JAN-11
5 8500 9months 12-MAR-07 27-MAR-11
6 10000 20months 17-SEP-07 01-AUG-11
7 25000 7months 17-NOV-07 26-JUL-11
8 100000 6months 05-MAY-07 21-JUN-11
9 35000 16months 28-FEB-08 21-JUN-11
10 5000 16months 02-DEC-08 19-AUG-11
joinning query :
select emp_no,
emp_name,
dpt_no,
salary
from emp
join salary on emp.dpt_no=salary.dpt_no
but am getting error is"column is amguously defined". How to resolve this problem?
You need to fully qualify the columns in the select list (the way it's done in the JOIN condition). Otherwise Oracle wouldn't know from which table the column dept_no should be taken.
select emp.emp_no,
emp.emp_name,
emp.dpt_no,
salary.salary
from emp
join salary on emp.dpt_no=salary.dpt_no;
It's good coding style to always qualify the columns - at least in a query involving more than one table - even if they are not ambigous.
If you don't want to type the full table name, you can use a (maningful) alias:
select emp.emp_no,
emp.emp_name,
emp.dpt_no,
sal.salary,
sal.period
from emp
join salary sal
on emp.dpt_no = sal.dpt_no;
If the columnname is the same in tables (salary and emp) and youre joining the tables, you have to specify form wich table you want to selecte the column (salary or from emp)
in youre case the solution is to use salary.dpt_no instead of dpt_no
select emp_no,emp_name, salary.dpt_no,salary from emp join salary on emp.dpt_no=salary.dpt_no