I'm using codeigniter framework here I'm getting the value through datatable now I want to get the data from two table like below.
Table 1
id Name Age
1 Sam 26
2 Geo 36
5 Sant 12
Table 2
id Name Age
3 Jhon 25
2 Geo 45
7 Negir 17
Result
id Name Age
1 Sam 26
2 Geo 45
3 Jhon 25
5 Sant 12
7 Negir 17
You can see I merged two tables and id 2 has 45 which override the first one. Kindly help me.
You can use this sql query to get records
SELECT id,name,age
FROM table1
GROUP BY id,name
UNION
SELECT id,name,age
FROM table2
GROUP BY id,name order by id asc
We can use this query in codeigniter way:-
$this->db->query("SELECT id,name,age FROM table1 GROUP BY id,name UNION SELECT id,name,age FROM table2 GROUP BY id,name order by id asc");
What I do in such a situation is to get the compiled_select() of the individual select queries, then I merge them into a single query with the help of $this->db->query().
Here's what you can do:
$this->db->select('id,name,age');
$this->db->from('table1');
$query_1 = $this->db->get_compiled_select();
$this->db->select('id,name,age');
$this->db->from('table2');
$query_2 = $this->db->get_compiled_select();
$final_query = $this->db->query($query_1 . ' UNION ' . $query_2);
$result = $final_query->result_array();
You can then get your values from the $result variable as usual.
Related
I want to select DISTINCT results from the user_id column but I need the corresponding columns as well.
Result set needs to return two role_id that are Distnct user_id and be not an 'Unassigned' status.
The query I am using:
SELECT role_id, user_id, role_code, status_code FROM table where school_id=5 and status_code= 'DRAFT';
This an example of my table:
ROLE_ID USER_ID SCHOOL_ID CAMPUS_ID ROLE_CODE STATUS_CODE
1 4 5 7 Unassigned DRAFT
2 4 5 7 TEST DRAFT
3 4 5 8 TEST DRAFT
4 5 5 9 Unassigned DRAFT
5 5 5 9 TEST DRAFT
6 5 5 10 TEST DRAFT
I have tried to add group by based on user_id but I get an ORA-00979.
You can use ROW_NUMBER() to identify the rows you want. For example:
select *
from (
select t.*,
row_number() over(partition by user_id order by role_id) as rn
from t
where role_code <> 'Unassigned'
) x
where rn = 1
DISTINCT is across the entire set of columns and not for one specific column. Therefore, if you want to get the DISTINCT rows which are not Unassigned you can use:
SELECT DISTINCT
role_id,
user_id,
role_code,
status_code
FROM table
where school_id = 5
and status_code = 'DRAFT'
and role_code != 'Unassigned';
If you want to get a single row for each user_id then you can use GROUP BY and find the minimum role_id:
SELECT MIN(role_id) AS role_id,
user_id,
MIN(role_code ) KEEP (DENSE_RANK FIRST ORDER BY role_id) AS role_code,
MIN(status_code) KEEP (DENSE_RANK FIRST ORDER BY role_id) AS status_code
FROM table
where school_id = 5
and status_code = 'DRAFT'
and role_code != 'Unassigned'
GROUP BY
user_id;
Is there a way we can use an aggregate function inside a CASE statement as part of the same select ?
When i run the query below i get the following error ORA-00937: not a single-group group function
00937. 00000 - "not a single-group group function".
SELECT
A.id id,
SUM(B.quantity) quantity ,
MAX(CASE WHEN nvl(A.threshold,0) > SUM(B.quantity) THEN 'T' ELSE 'F' END ) late
FROM
TableB B ,
TableA A
WHERE B.Type in ('ATYPE,'BTYPE') AND A.nKey = B.id
GROUP BY
A.id
Table B
id quantity Type
9 10 Type A
9 11 Type B
10 5 Type A
Table A
id nkey threshold
1 9 15
2 10 10
Result
id quantity late
1 21 F
2 5 T
You just need to use the aggregate function for threshold or add threshold in the group by list:
either replace nvl(A.threshold,0) with min(nvl(A.threshold,0))
or
use the following GROUP BY:
group by a.id, a.threshold
I have users name in column users, I want to display all users as a column and the order of representation of column must be in descending order of their sum of data.
query:
select *
from (
select sum(tran_count) over (partition by schema) as table_name
from main_table
) pivot (sum(tran_count) for users in ('abc','lmn','pqr'));
ans:
schema table abc lmn pqr
pm sector 32 216 12
history trn 321 61 4
tap issuer 43 325 2
count: 396 602 18
so I want to represent the column abc,lmn and pqr in order of count of their data:
required answer:
schema table lmn abc pqr
pm sector 216 32 12
history trn 61 321 4
tap issuer 325 43 2
You cannot use (sub)query in pivot's in clause. What you can do is to rank users according to their summaric values and use these three values (1, 2, 3) in in. Then either use my inner query, which presents user names and sums in separate columns or make a final union, where names are listed in first row and sums in rows below as strings.
with t as (
select *
from (
select dense_rank() over (order by smu desc, users) rn,
schema_, table_, users, smt
from (
select schema_, table_, users, sum(tran_count) smt,
sum(sum(tran_count)) over (partition by users) smu
from main_table
group by schema_, table_, users))
pivot (max(users) name, max(smt) smt for rn in (1 u1, 2 u2, 3 u3)))
select null schema_, null table_, u1_name u1, u2_name u2, u3_name u3
from t where rownum = 1 union all
select schema_, table_, to_char(u1_smt), to_char(u2_smt), to_char(u3_smt)
from t
dbfiddle demo
If you really need to put user names in headers then you have to use dynamic SQL or external code-writing-code technique.
I don't know if you really have columns like table or schema, these are reserved words, also once you write tran_count and in title count_date, so I am somewhat confused. But you can see in the linked dbfiddle working example with columns schema_, table_, users, tran_count.
I group my table by months
SELECT TO_CHAR (created, 'YYYY-MM') AS operation, COUNT (id)
FROM user_info
WHERE created IS NOT NULL
GROUP BY ROLLUP (TO_CHAR (created, 'YYYY-MM'))
2015-04 1
2015-06 10
2015-08 22
2015-09 8
2015-10 13
2015-12 5
2016-01 25
2016-02 37
2016-03 24
2016-04 1
2016-05 1
2016-06 2
2016-08 2
2016-09 7
2016-10 103
2016-11 5
2016-12 2
2017-04 14
2017-05 2
284
But the records don't cover all the months.
I would like the output to include all the months, with the missing ones displayed in the output with a default value:
2017-01 ...
2017-02 ...
2017-03 ZERO
2017-04 ZERO
2017-05 ...
Oracle has a good array of date manipulation functions. The two pertinent ones for this problem are
MONTHS_BETWEEN() which calculates the number of months between two dates
ADD_MONTHS() which increments a date by the given number of months
We can combine these functions to generate a table of all the months spanned by your table's records. Then we use an outer join to conditionally join records from USER_INFO to that calendar. When no records match count(id) will be zero.
with cte as (
select max(trunc(created, 'MM')) as max_dt
, min(trunc(created, 'MM')) as min_dt
from user_info
)
, cal as (
select add_months(min_dt, (level-1)) as mth
from cte
connect by level <= months_between(max_dt, min_dt) + 1
)
select to_char(cal.mth, 'YYYY-MM') as operation
, count(id)
from cal
left outer join user_info
on trunc(user_info.created, 'mm') = cal.mth
group by rollup (cal.mth)
order by 1
/
I have a table X
ID A B
--------------
1 abc 27
1 - 28
2 - 33
3 xyz 41
3 - 07
I need output as
ID A B
--------------
1 abc 27
2 - 33
3 xyz 41
I tried doing
max(A) OVER (PARTITION BY ID) as the_value
but it did not work. I can still see all the rows in the output table.
I was wondering if somebody has come across a similar situation and has a solution to this ?
you can use this simple trick for getting the full record for which some column is maxed:
select original.* from
(select ID,max(B) as B from Tbl group by ID ) maxB
inner join
(select * from Tbl ) original
on original.ID = maxB.ID and original.B = maxB.B
now this is of course an overkill code. you can also do:
select Tbl.* from
(select ID,max(B) as B from Tbl group by ID ) maxB
inner join
Tbl
on Tbl.ID = maxB.ID and Tbl.B = maxB.B
but the first version is more of a template to do whatever you want with further columns, fields, conditions joins etc.