I have some data in a bigquery table that contains 3 relevant data fields:
A, B and C
A + B SHOULD be a unique pair; This means that a value from column B should NOT have multiple, different, values from Column A.
A B C
1111 XXXX10 2019-01-01
1111 XXXX10 2019-01-02
1111 XXXX10 2019-01-03
1111 XXXX10 2019-01-04
2222 XXXX11 2019-01-01
2222 XXXX11 2019-01-02
2222 XXXX11 2019-01-03
3333 XXXX12 2019-01-01
4444 XXXX13 2019-01-01
5555 XXXX10 2019-01-01
6666 XXXX11 2019-01-03
In the above example, i want to run a query where: Column B > 1 unique value in column A values. The data sample above would return the result below:
A B C
2222 XXXX11 2019-01-03
6666 XXXX11 2019-01-03
1111 XXXX10 2019-01-01
5555 XXXX10 2019-01-01
any suggestions would be great
thanks!
Below is for BigQuery Standard SQL
#standardSQL
SELECT a, b, ANY_VALUE(c) c
FROM (
SELECT b, ARRAY_AGG(STRUCT(a, c)) arr
FROM `project.dataset.table`
GROUP BY b
HAVING COUNT(DISTINCT a) > 1
), UNNEST(arr)
GROUP BY a, b
If to apply to sample data from your question
WITH `project.dataset.table` AS (
SELECT 1111 a, 'XXXX10' b, '2019-01-01' c UNION ALL
SELECT 1111, 'XXXX10', '2019-01-02' UNION ALL
SELECT 1111, 'XXXX10', '2019-01-03' UNION ALL
SELECT 1111, 'XXXX10', '2019-01-04' UNION ALL
SELECT 2222, 'XXXX11', '2019-01-01' UNION ALL
SELECT 2222, 'XXXX11', '2019-01-02' UNION ALL
SELECT 2222, 'XXXX11', '2019-01-03' UNION ALL
SELECT 3333, 'XXXX12', '2019-01-01' UNION ALL
SELECT 4444, 'XXXX13', '2019-01-01' UNION ALL
SELECT 5555, 'XXXX10', '2019-01-01' UNION ALL
SELECT 6666, 'XXXX11', '2019-01-03'
)
result is
Row a b c
1 1111 XXXX10 2019-01-01
2 5555 XXXX10 2019-01-01
3 2222 XXXX11 2019-01-01
4 6666 XXXX11 2019-01-03
Related
Is there a way to use Currency Format (or some other standard formatter) to format numbers like this in Oracle Apex:
1,000,000 => 1.00M
1,234,567 => 1.23M
1,234,567,890 => 1234.57M
Not declaratively, as far as I can tell. But, you can do it yourself (perhaps).
col is original value
c1 is that number (col) divided by a million
c2 rounds the result to the 2nd decimal (which is OK, but - decimals are missing (see 1)
c3 uses to_char function
final_result is c3 concatenated with an M
Note that col, c1 and c2 are numbers, while c3 and final_result are strings.
SQL> with test (col) as
2 (select 1000000 from dual union all
3 select 1234567 from dual union all
4 select 1234567890 from dual
5 )
6 select col,
7 col/1e6 c1,
8 round(col/1e6, 2) c2,
9 to_char(col/1e6, 'fm99990D00') c3,
10 --
11 to_char(col/1e6, 'fm99990D00') || 'M' final_result
12 from test;
COL C1 C2 C3 FINAL_RESULT
---------- ---------- ---------- --------- ---------------
1000000 1 1 1,00 1,00M
1234567 1,234567 1,23 1,23 1,23M
1234567890 1234,56789 1234,57 1234,57 1234,57M
SQL>
This question already has an answer here:
how to duplicate my sql results? [duplicate]
(1 answer)
Closed 2 years ago.
Table A is:
--------------
C1 C2
--------------
A 3
B 2
--------------
select * from
(
select 'A' as C1, 3 as C2 from dual
union all
select 'B' as C1, 2 as C2 from dual
)
I want to get the following result view with one query statement:
--------------
C1 N1
--------------
A 1
A 2
A 3
B 1
B 2
--------------
I need to generate rows as many as C2 value
Is this possible?
Thank you.
We can handle this via the use of a calendar/sequence table. Consider:
WITH nums AS (
SELECT 1 AS val FROM dual UNION ALL
SELECT 2 FROM dual UNION ALL
SELECT 3 FROM dual
)
SELECT
a.C1,
n.val AS N1
FROM TableA a
INNER JOIN nums n
ON n.val <= a.C2
ORDER BY
a.C1,
n.val;
Demo
Note that in practice, you might use a dedicated table containing a sequence of numbers to cover all possible values in your table. Or, you might use an Oracle sequence.
Alternatively:
SQL> with test as
2 (select 'A' as C1, 3 as C2 from dual
3 union all
4 select 'B' as C1, 2 as C2 from dual
5 )
6 select c1, column_value n1
7 from test cross join table(cast(multiset(select level from dual
8 connect by level <= c2
9 ) as sys.odcinumberlist))
10 order by c1, column_value;
C N1
- ----------
A 1
A 2
A 3
B 1
B 2
SQL>
I have one table t as below
Customer _no | receipt_no
----------------------------
A | 123
A. | 234
A. | 345
B. | 465
B. | 675
I want result as
Customer _no | receipt_1 | receipt_2
A. | 123. | 234
A. | 345. | Null
B. | 465. | 675
Please suggest how to do this
If I understood it correctly, you want to have two columns for each customer. If that's so, here's one option.
SQL> with test (cno, rno) as
2 (select 'A', 123 from dual union all
3 select 'A', 234 from dual union all
4 select 'A', 345 from dual union all
5 select 'A', 444 from dual union all
6 select 'A', 555 from dual union all
7 select 'B', 456 from dual union all
8 select 'B', 675 from dual
9 ),
10 inter as
11 (select cno, rno,
12 row_number() over (partition by cno order by cno, rno) rn,
13 round(row_number() over (partition by cno order by cno, rno) /2) grp
14 from test
15 )
16 select cno,
17 max(decode(mod(rn, 2), 1, rno)) r1,
18 max(decode(mod(rn, 2), 0, rno)) r2
19 from inter
20 group by cno, grp
21 order by cno, grp;
C R1 R2
- ---------- ----------
A 123 234
A 345 444
A 555
B 456 675
SQL>
I have a scenario and build a Oracle query for it.
Table Columns: Plan_No, Invoice_No,Order_Dt. One plan will have more than one invoice.
I want get this output:
Plan_No Invoice_No Order_Dt Row_No
A1 1001 23-May-17 1
A1 1002 10-Apr-17 2
A1 1003 12-Jan-17 3
A1 1004 11-Nov-16 4
B1 1001 10-May-17 1
B1 2008 10-Feb-17 2
B1 3308 12-Dec-16 3
C1 5007 23-May-17 1
C1 5585 10-Apr-17 2
C1 52545 12-Jan-17 3
C1 5228 11-Nov-16 4
C1 21488 2-Jan-16 5
C1 51546 16-Apr-15 6
I think you can do something like this:
SELECT
ROW_NUMBER() OVER(PARTITION BY plan_no ORDER BY Invoice_No) AS row_nbr,
*
FROM
table
Table A
A1 A2
1 7
2 8
1 9
Table B
A1 B2
1 2
2 3
i want something like this
select A.A1,sum(case when distinct A.A1 then B2),sum(A.A2) from
A,B
where A.A1=B.A1(+)
group by A.A1
After joining my table will be
A1 A2 B2
1 7 2
2 8 3
1 9 2
Resulting Table
A1 A2 B2
1 7+9 2(only once)
2 8 3
how to get sum of B2 when distinct A1 after joining the tables as stated above.
Thanks in advance
Use JOIN and GROUP BY.
Query
SELECT t1.A1, SUM(t1.A2) AS A1, SUM(t2.B2) AS B2
FROM TableA t1
JOIN TableB t2
ON t1.A1 = t2.A1
GROUP BY t1.A1;
Since table_b.a1 is unique, the best way to do this would be to work out the sum of table_a.a2 first to reduce the number of rows you're joining against, and then join to table_b. Then you don't need to worry about summing the distinct table_b.b2 values, which you would otherwise have to do.
WITH table_a AS (SELECT 1 a1, 7 a2 FROM dual UNION ALL
SELECT 2 a1, 8 a2 FROM dual UNION ALL
SELECT 1 a1, 9 a2 FROM dual),
table_b AS (SELECT 1 a1, 2 b2 FROM dual UNION ALL
SELECT 2 a1, 3 b2 FROM dual)
-- end of mimicking your two tables with sample_data in them;
-- see the sql below:
SELECT ta.a1,
ta.a2,
tb.b2
FROM (SELECT a1, SUM(a2) a2
FROM table_a
GROUP BY a1) ta
INNER JOIN table_b tb ON ta.a1 = tb.a1;
A1 A2 B2
---------- ---------- ----------
1 16 2
2 8 3
If you absolutely must join the two tables first (I don't recommend; this is making more work for the database to do), then you could do something like:
WITH table_a AS (SELECT 1 a1, 7 a2 FROM dual UNION ALL
SELECT 2 a1, 8 a2 FROM dual UNION ALL
SELECT 1 a1, 9 a2 FROM dual),
table_b AS (SELECT 1 a1, 2 b2 FROM dual UNION ALL
SELECT 2 a1, 3 b2 FROM dual)
SELECT ta.a1,
SUM(ta.a2) a2,
MAX(tb.b2) b2
FROM table_a ta
INNER JOIN table_b tb ON ta.a1 = tb.a1
GROUP BY ta.a1;
A1 A2 B2
---------- ---------- ----------
1 16 2
2 8 3
Since there can only be one distinct value for table_b.b2 per table_a.a1, we can just pick one of the values to use via MAX (we could have used MIN or SUM(distinct tb.b2) instead, fyi).