Best SQL query to get unique sets from below table - sql

I have a below table
Select X,Y from T
X | Y
------
1 | 2
1 | 3
2 | 1
3 | 5
3 | 1
Column X and Y holds Strings, I gave numbers just for example.
I need output from this table as below
1,2
1,3
3,5
i,e, Unique sets from the table. Out of Row 1 (1,2) and Row 3 (2,1), I need only one set, because (1,2)=(2,1) in my set. Similarly (1,3)=(3,1).
So unique sets in this table are (1,2) (1,3) and (3,5).
I tried below SQL, let me know if there is a better way, as I am not sure whether I can use '>' or '<' with ROWID
SELECT X||','||Y FROM T t1
WHERE NOT EXISTS (SELECT 1 FROM T t2
WHERE t1.X=t2.Y AND t1.Y=t2.X and t1.ROWID>t2.ROWID)

select distinct least(x,y), greatest(x,y)
from the_table;
least() and greatest() put the values into an order so that 1,2 and 2,1 are returned as 1,2. The distinct then removes the duplicates

DISTINCT gets you distinct rows, so all you need to do is to have your pairs ordered, first the smaller then the larger. You do this with LEAST and GREATEST.
select distinct least(x,y) || ',' || greatest(x,y)
from t;

Related

Get DISTINCT list of values within GroupBy sql

I have this Table
place subplace
A x
A x
B x
A y
B y
A y
A z
When I do this query
SELECT place, count(distinct subplace) AS count_subplace
from table
GROUP BY place
I get result
place count_subplace
A 3
B 2
Now I want the list of the distinct elements rather than the count
I know we can use string_agg
how can I call distinct and also groupby in it
I want result something like
place subplace_list
A x,y,z
B x,y
I have tried this which won't work
SELECT place, string_agg(distinct subplace,',') AS list_subplace
from table
GROUP BY place
Because of string_agg didn't support distinct inside.
You can try to use a subquery to distinct your result set.
Query 1:
SELECT place, string_agg(subplace,',') AS list_subplace
from (select distinct place,subplace from t) t1
GROUP BY place
Results:
| place | list_subplace |
|-------|---------------|
| A | x,y,z |
| B | x,y |

How to unnest two lists from two columns in BigQuery without cross product, as individual rows

I have a table in BigQuery, it has two columns, each column contains an array. for a given row, both columns will contain arrays of the same length, but that length can vary from row to row:
WITH tbl AS (
select ['a','b','c'] AS one, [1,2,3] as two
union all
select ['a','x'] AS two, [10,20] as two
)
select * from tbl
So the table will look like:
row | one | two
-----------------------
1 | [a,b,c] | [1,2,3]
2 | [a,x] | [10,20]
I would like to unnest in such a way that each row, in the new table, will have an element of an array from column1 and an corresponding element from column2. So from the table above, I am looking to get:
row | one | two
---------
1 | a | 1
2 | b | 2
3 | c | 3
4 | a | 10
5 | x | 20
Any help would be much appreciated! Thanks!
below is for BigQuery Standard SQL
#standardSQL
SELECT z.*
FROM `project.dataset.table` t,
UNNEST(ARRAY(
SELECT AS STRUCT one, two
FROM UNNEST(one) one WITH OFFSET
JOIN UNNEST(two) two WITH OFFSET
USING(OFFSET)
)
) z
You can test, play with above using sample data from your question - result will be
Row one two
1 a 1
2 b 2
3 c 3
4 a 10
5 x 20
I dont fully understand the syntax, could you please explain it?
Explanation:
Step 1
for each row in table below array is calculated
ARRAY(
SELECT AS STRUCT one, two
FROM UNNEST(one) one WITH OFFSET
JOIN UNNEST(two) two WITH OFFSET
USING(OFFSET)
)
Elements of this array are structs with respective value from two column - they are being matched with each other by JOIN'ing on their positions in initial arrays (OFFSET)
Step 2
Then this array gets UNNEST'ed and cross JOIN'ed with respective row in the table - and whole row is actually ignored and only that struct (z) is being brought into to the output
Step 3
And finally to output not a a struct but rather as a separate columns - z.* is used
Hope this helped :o)

Multiple row count from single table

How do I get counts of multiple records from a single table using db2 query?
Suppose I want to get the count of 1 record am using:
select count(*) from schema.table where record value='x'
What I need is a count of multiple records from the same table in separate rows for each record. I am trying something like:
select count(*) from schema.table where record in('x','y','z')
The queried result combines the value into one single value in a single row, which I don't want.
I almost agree with the Mureinik. You can add a WHERE clause to get multiple row counts from only those records you want, e.g. (x, y, z)
SELECT record, COUNT(*) AS 'count'
FROM schema.table WHERE record IN ('x', 'y', 'z')
GROUP BY record
result:
------------------
| record | count |
------------------
| x | 100 |
| y | 150 |
| z | 50 |
------------------
The group by syntax breaks the table up into groups, and allows you to perform aggregate functions (count, in your case) on each one separately:
SELECT record, COUNT(*)
FROM schema.table
GROUP BY record

Select substring from a column in SQL

How do I match a substring on another table?
Table 1:
Reference | Value
----------+-------
1 | 02.02.2011 07:07:00 498-123456-741
5 | 123-789654-100
5 | 123-789654-100
Table 2:
Reference | Code
----------+-------
5 | 123-789654-700
1 | 498-123456-100
I want to count the value from table one on table 2
select count(value) as count
from table 1 join table 2 on substring(value,0,12)=substring(code,0,12)
where reference='5'
If it the value is present in Table 2 it gives me a count of 2.
select count(value) as count
from table 1 join table 2 on substring(value,20,12)=substring(code,0,12)
where reference='1'
So the first query works fine the second query when a value comes in like 02.02.2011 07:07:00 498-123456-741 it doesn't compare it to table to even though that value is there, in Table 2 it will always be a substring of (0,12).
The syntax is like this : SUBSTRING ( expression ,start , length )
For example :
SELECT x = SUBSTRING('abcdef', 2, 3);
Here is the result set:
x
----------
bcd
You should do like this :
select count(*) as count from
table 1 join table 2
on substring(value,20,12)=substring(code,0,12)
Do this
SELECT SUBSTRING('w3resource', startingIndex, lengthForRequiredString);
Example
SELECT SUBSTRING(column_name, 4, 3);

Insert multiple values and Insert value in parallel

I have a question about SQL in parallel queries. For example, suppose that I have this query:
INSERT INTO tblExample (num) VALUES (1), (2)
And this query:
INSERT INTO tblExample (num) VALUES (3)
The final table should looked like this:
num
---
1
2
3
But I wonder if there is an option that those two queries will run in parallel and the final table will be looked like this:
num
---
1
3
2
Someone know the answer?
Thanks in advance!
There is no order in sql. You can sort your queries by adding an ORDER BY clause
SELECT * FROM tblExample ORDER BY num
Or you could add a timestamp column to the table and order by that.
How your table "looks" depends on how you asked for it (in the SELECT statement). Without an ORDER BY clause, the order of your table is undefined:
ORDER BY is the only way to sort the rows in the result set. Without this clause, the relational database system may return the rows in any order. If an ordering is required, the ORDER BY must be provided in the SELECT statement sent by the application.
For example:
SELECT num FROM tblExample ORDER BY num ASC
1
2
3
SELECT num FROM tblExample ORDER BY num DESC
3
2
1
If you want to order your columns manually, you can add a new column and sort on it:
+-----+-------+
| num | order |
+-----+-------+
| 1 | 1 |
| 2 | 3 |
| 3 | 2 |
+-----+-------+
SELECT num FROM tblExample ORDER BY order ASC
1
3
2