I have in my Oracle Responsys Database a table that contains records with amongst other two variables:
status
location_id
I want to count the number of records grouped by status and location_id, and display it as a pivot table.
This seems to be the exact example that appears here
But when I use the following request :
select * from
(select status,location_id from $a$ )
pivot (count(status)
for location_id in (0,1,2,3,4)
) order by status
The values that appear in the pivot table are just the column names :
output :
status 0 1 2 3 4
-1 0 1 2 3 4
1 0 1 2 3 4
2 0 1 2 3 4
3 0 1 2 3 4
4 0 1 2 3 4
5 0 1 2 3 4
I also gave a try to the following :
select * from
(select status,location_id , count(*) as nbreports
from $a$ group by status,location_id )
pivot (sum(nbreports)
for location in (0,1,2,3,4)
) order by status
but it gives me the same result.
select status,location_id , count(*) as nbreports
from $a$
group by status,location_id
will of course give me the values I want, but displaying them as a column and not as a pivot table
How can I get the pivot table to have in each cell the number of records with the status and location in row and column?
Example data:
CUSTOMER,STATUS,LOCATION_ID
1,-1,1
2,1,1
3,2,1
4,3,0
5,4,2
6,5,3
7,3,4
The table data types :
CUSTOMER Text Field (to 25 chars)
STATUS Text Field (to 25 chars)
LOCATION_ID Number Field
Please check if my understanding for your requirement is correct, you can do vice versa for the location column
create table test(
status varchar2(2),
location number
);
insert into test values('A',1);
insert into test values('A',2);
insert into test values('A',1);
insert into test values('B',1);
insert into test values('B',2);
select * from test;
select status,location,count(*)
from test
group by status,location;
select * from (
select status,location
from test
) pivot(count(*) for (status) in ('A' as STATUS_A,'B' as STATUS_B))
Related
I inserted all the rows of a view to a delta table, but after running a query for a particular value I get below results.
Can someone explain to me how this is possible?
A is View and B is Delta(databricks) table.
1.
Select count(*) from A
result: 102.321
2.
Select * from A where id = '11'
id
date
unit
11
2022-09-02
4
3.
Insert Into B Select * From A
OR
CREATE OR REPLACE TABLE B AS ( SELECT * FROM A)
Select count(*) from B '
result: 101.372
5.
Select * from B where id = '11'
id
date
unit
11
2022-09-02
2
I have a table
rate_id service_id
1 1
1 2
2 1
2 3
3 1
3 2
4 1
4 2
4 3
I need to find and insert in a table the unique combinations of sevice_ids by rate_id...but when the combination is repeated in another rate_id I do not want it to be inserted
In the above example there are 3 combinations
1,2 1,3 1,2,3
How can I query the first table to get the unique combinations?
Thanx!
Try doing something like this:
DECLARE #TempTable TABLE ([rate_id] INT, [service_id] INT)
INSERT INTO #TempTable
VALUES (1,1),(1,2),(2,1),(2,3),(3,1),(3,2),(4,1),(4,2),(4,3)
SELECT DISTINCT
--[rate_id], --include if required
(
SELECT
CAST(t2.[service_id] AS VARCHAR) + ' '
FROM
#TempTable t2
WHERE
t1.[rate_id] = t2.[rate_id]
ORDER BY
t2.[rate_id]
FOR XML PATH ('')
) AS 'Combinations'
FROM
#TempTable t1
I put the values in a table variable just for ease of testing the SELECT query.
I like to have my query count one column two times in my select based on the value. So for example.
input: table
id | type
-------------|-------------
1 | 1
2 | 1
3 | 2
4 | 2
5 | 2
output: query (in 1 row, not two):
countfirst = 2 (two times 1)
countsecond = 3 (three times 2)
An default count in an select counts all rows in the query. But i like to count rows based
on an number without limiting the query. When using for example WHERE type = '1', type 2
gets filtered and cannot be counted anymore.
Is there an solution for this case in SQL?
--- EXAMPLE USE (situation above is simplefied but case is the same) ---
With one query i get all cars grouped by type from an table. There are two type signs: yellow (in db 1) and grey (in db 2). So in that query i have the folowing output:
Renault - ten times found - two yellow signs - eight grey signs
Create a table, script is given below.
CREATE TABLE [dbo].[temptbl](
[id] [int] NULL,
[type] [int] NULL
) ON [PRIMARY]
Execute the insert script as
insert into [temptbl] values(1,1)
insert into [temptbl] values(2,1)
insert into [temptbl] values(3,2)
insert into [temptbl] values(4,2)
insert into [temptbl] values(5,2)
Then execute the query.
;WITH cte as(
SELECT [type], Count([type]) cnt
FROM temptbl
GROUP BY [type]
)
SELECT * FROM cte
pivot (Sum([cnt]) for [type] in ([1],[2])) as AvgIncomePerDay
You can use the GROUP BY clause as Mureinik suggested, but with the addition of a WHERE clause to filter the results.
Below shows the results for type = 1 (assuming type is an INT:
SELECT type, COUNT(*) AS NoOfRecords
FROM table
WHERE type IN (1)
GROUP BY type
So if we wanted 1 and 2 we can use:
SELECT type, COUNT(*) AS NoOfRecords
FROM table
WHERE type IN (1, 2)
GROUP BY type
Lastly, that IN statement can pull type from another query:
SELECT type, COUNT(*) AS NoOfRecords
FROM table
WHERE type IN (SELECT type FROM someOtherTable)
GROUP BY type
Note: I would like to do this in a single SQL statement. not pl/sql, cursor loop, etc.
I have data that looks like this:
ID String
-- ------
01 2~3~1~4
02 0~3~4~6
03 1~4~5~1
I want to provide a report that somehow pivots the values of the String column into distinct rows such as:
Value "Total number in table"
----- -----------------------
1 3
2 1
3 2
4 3
5 1
6 1
How do I go about doing this? It's like a pivot table but I am trying to pivot the data in a column, rather than pivoting the columns in the table.
Note that in real application, I do not actually know what the values of the String column are; I only know that the separation between values is '~'
Given this test data:
CREATE TABLE tt (ID INTEGER, VALUE VARCHAR2(100));
INSERT INTO tt VALUES (1,'2~3~1~4');
INSERT INTO tt VALUES (2,'0~3~4~6');
INSERT INTO tt VALUES (3,'1~4~5~1');
This query:
SELECT VALUE, COUNT(*) "Total number in table"
FROM (SELECT tt.ID, SUBSTR(qq.value, sp, ep-sp) VALUE
FROM (SELECT id, value
, INSTR('~'||value, '~', 1, L) sp -- 1st posn of substr at this level
, INSTR(value||'~', '~', 1, L) ep -- posn of delimiter at this level
FROM tt JOIN (SELECT LEVEL L FROM dual CONNECT BY LEVEL < 20) q -- 20 is max #substrings
ON LENGTH(value)-LENGTH(REPLACE(value,'~'))+1 >= L
) qq JOIN tt on qq.id = tt.id)
GROUP BY VALUE
ORDER BY VALUE;
Results in:
VALUE Total number in table
---------- ---------------------
0 1
1 3
2 1
3 2
4 3
5 1
6 1
7 rows selected
SQL>
You can adjust the maximum number of items in your search string by adjusting the "LEVEL < 20" to "LEVEL < your_max_items".
Here is a brief description of the tables I'm working with in Oracle 10g:
Notes:
Table : jnldetail : Single row with data as shown.
There are multiple package id's attached to the same bill_ref_no for an account. Therefore, I'm trying to update "jnldetail " with the multiple package_id's.
Relation between index_bill_ref and bill_ref_no : 1 - 1
Relation between account_no and ( index_bill_ref and bill_ref_no ) : 1 - Many
**Table : jnldetail** :
account_no bill_ref_no amount
8594822 74282843 822
I'm adding another column package_id with the following command:
alter table jnldetail add package_id number(10)
**table: bill_invoice**:
account_no bill_ref_no index_bill_ref
8594822 74282843 763653495
**table: bill_invoice_detail**:
index_bill_ref package_id component_id
763653495 20000077 20000177
763653495 20000250 20000528
763653495 13000019 13000137
**Expected Result:**
**Table : jnldetail** :
account_no bill_ref_no amount package_id
8594822 74282843 822 20000077
8594822 74282843 822 20000250
8594822 74282843 822 13000019
My Query is:
UPDATE jnldetail tp
SET tp.package_id = (
select
t1.package_id
from bill_invoice_detail t1
, bill_invoice t2
where
t1.index_bill_ref = t2.index_bill_ref
and
t2.account_no = tp.account_no
)
The error message is : ora 01427 : single row subquery returns more than one row
Any inputs will be helpful.
Thanks!
The problem is that you're trying to set tp.package_id to more than one number, because your subquery is returning more than one result, e.g. 20000077 and 13000019. You'll need to alter the subquery so that only one value is returned.
Why not keep the tables separate and use a join when you are ready to get the complete data?
This is tricky for two reasons:
1) you want to update the existing row, and want to add two new rows
2) the two new rows need the data from both the original jnldetail table (amount) and the bill_invoice tables (package_id)
To address 1, you can use the MERGE statement, but because of 2, the jnldetail is needed in the using clause of the MERGE statement.
Here is your example:
SQL> create table jnldetail (account_no, bill_ref_no, amount)
2 as
3 select 8594822, 74282843, 822 from dual
4 /
Tabel is aangemaakt.
SQL> alter table jnldetail add package_id number(10)
2 /
Tabel is gewijzigd.
SQL> create table bill_invoice (account_no, bill_ref_no, index_bill_ref)
2 as
3 select 8594822, 74282843, 763653495 from dual
4 /
Tabel is aangemaakt.
SQL> create table bill_invoice_detail (index_bill_ref, package_id, component_id)
2 as
3 select 763653495, 20000077, 20000177 from dual union all
4 select 763653495, 20000250, 20000528 from dual union all
5 select 763653495, 13000019, 13000137 from dual
6 /
Tabel is aangemaakt.
The tables as you described them.
SQL> UPDATE jnldetail tp
2 SET tp.package_id =
3 ( select t1.package_id
4 from bill_invoice_detail t1
5 , bill_invoice t2
6 where t1.index_bill_ref = t2.index_bill_ref
7 and t2.account_no = tp.account_no
8 )
9 /
( select t1.package_id
*
FOUT in regel 3:
.ORA-01427: single-row subquery returns more than one row
Your update statement fails, because you try to assign the result of a 3-rows-returning-query to a single column.
Here is the MERGE statement:
SQL> merge into jnldetail jd
2 using ( select bi.account_no
3 , bi.bill_ref_no
4 , jd.amount
5 , bid.package_id
6 , row_number() over (partition by bi.account_no,bi.bill_ref_no,bi.index_bill_ref order by null) rn
7 from bill_invoice bi
8 , bill_invoice_detail bid
9 , jnldetail jd
10 where bi.index_bill_ref = bid.index_bill_ref
11 and bi.account_no = jd.account_no
12 and bi.bill_ref_no = jd.bill_ref_no
13 ) bi
14 on ( jd.account_no = bi.account_no
15 and jd.bill_ref_no = bi.bill_ref_no
16 and bi.rn = 1
17 )
18 when matched then
19 update set package_id = package_id
20 when not matched then
21 insert values (bi.account_no,bi.bill_ref_no,bi.amount,bi.package_id)
22 /
3 rijen zijn samengevoegd.
Note that we pick an arbitrary row to be updated: the one with rn = 1.
It leads to the desired result set:
SQL> select * from jnldetail
2 /
ACCOUNT_NO BILL_REF_NO AMOUNT PACKAGE_ID
---------- ----------- ---------- ----------
8594822 74282843 822 13000019
8594822 74282843 822 20000077
8594822 74282843 822 20000250
3 rijen zijn geselecteerd.
Regards,
Rob.