How can i find different of this sql 2 rows - sql

i want to count sum of this after minus please help me
SELECT t1.*
FROM table1 t1
MINUS
SELECT t2.*
FROM table2 t1
JOIN customers c ON t1.number = t2.number;

Another way is using CTE
With cte as (SELECT t1.*
FROM table1 t1
MINUS
SELECT t2.*
FROM table2 t1
JOIN customers c ON t1.number = t2.number)
Select count(*) from cte;

one way is :
select count(*) from (
SELECT *
FROM table1 t1
MINUS
SELECT *
FROM table2 t1
JOIN customers c ON t1.number = t2.number
) t

I suspect that you really want:
select count(*)
from (select number
from table1
minus
select number
from customers
) t;
It seems really odd that you would have two tables (table1 and table2 in your question) with exactly the same columns.
In addition, this does something useful, which is to count the number of numbers in table1 that are not customers.

Related

How to Group By all fields nested tables in a Left Join query in BigQuery?

I have about 10 tables that I make one big nested tables by rounds with the following query:
R1 AS(
SELECT ANY_VALUE(Table1).*, ARRAY_AGG(( SELECT AS STRUCT Table2.* EXCEPT(ID))) AS Table2
FROM Table1 LEFT JOIN Table2 USING(ID)
GROUP BY Table1.ID),
R2 AS(
SELECT ANY_VALUE(R1).*, ARRAY_AGG(( SELECT AS STRUCT Table3.* EXCEPT(ID))) AS Table3
FROM R1 LEFT JOIN Table3 USING(ID)
GROUP BY R1.ID),
...
SELECT ANY_VALUE(R9).*, ARRAY_AGG(( SELECT AS STRUCT Table10.* EXCEPT(ID))) AS Table10
FROM R9 LEFT JOIN Table10 USING(ID)
The thing is that for example in my first table I can have two records with the same ID but some other fields will be different and I want to consider them as two distinct records and thus group by all the fields of the table while I join.
Then I want to do the same with all the "sub-table" (the R tables in the query), so I will able to group by all the fields of the nested tables.
How can I do it easily ?
I tried GROUP BY Table1.* but it doesn't work...
Thank you in advance
Try to_json_string:
...
FROM Table1 t1
...
GROUP BY to_json_string(t1)
You seem to want something like this:
select *
from table1 t1 left join
(select t2.*
from table2 t2
where true
qualify row_number() over (partition by t2.id order by t2.id) = 0
) t2
using (id)
This uses qualify instead of group by to fetch one row.
If you don't want all rows from from table1, you can whittle them down as well:
select *
from (select t1.*
from table1 t1
where true
qualify row_number() over (partition by id, col1, col2 order by id) = 1
) t1 left join
(select t2.*
from table2 t2
where true
qualify row_number() over (partition by t2.id order by t2.id) = 0
) t2
using (id)
How to Group By all fields ...?
I tried GROUP BY Table1.* but it doesn't work...
Consider below example
SELECT ANY_VALUE(t1).*,
ARRAY_AGG(( SELECT AS STRUCT t2.* EXCEPT(ID))) AS Table2
FROM Table1 t1 LEFT JOIN Table2 t2 USING(ID)
GROUP BY FORMAT('%t', t1)

Union two tables with one different column

I have two almost identical tables except one column.
table1
id name amount
1 nm1 15
2 nm2 20
table1
id name amt
1 nm1 15
2 nm2 20
Now I have other joins but I want to avoid have it all twice but rather have more simple sql code.
At the moment I have to do all twice:
select t1.id, t1.name, t1.amount from table1 t1
left outer join.......
union all
select t2.id, t2.name, t2.amt as amount from table2 t2
left outer join.......
I would like to have something like:
select t1.id, t1.name, t1.amount from (select * from table1 union all select * from table2) t1
but this one column "amount" prevents it.
Is there a way how to handle it?
Do the union all before the join:
select t.id, t.name, t.amount, . . .
from (select t1.* from table1 t1 union all
select t2.* from table2 t2
) t left outer join.......

table of the number of occurrences of numbers in the column postgresql

I have a table:
My select:
select regexp_split_to_table(t3."Id"::character varying,'') as s
from (select t1."Id" from table1 t1
union all
select t2."Id"from table2 t2) t3
order by s
Or also I can get a string '22173345566179111134546175622323811' with this:
select string_agg(t3."Id"::character varying,'') as s
from (select t1."Id" from table1 t1
union all
select t2."Id"from table2 t2) t3
I need to get a table with number|count data, I mean for any number to get a count of repetitions in the select, for example:
1 | 9
2 | 5
3 | 5
and so on..
PostgreSQL DBMS
Does this do what you want?
select id, count(*)
from (select t1."Id" from table1 t1
union all
select t2."Id" from table2 t2
) t3
group by id
order by id;
If I understand you right, you want a list of all digits, that exist in a set of IDs from two tables and the count of each digit, how often it appears in all these IDs. If so, you just need to GROUP BY a digit and use count().
SELECT s.d,
count(*) count
FROM (SELECT t1."Id"
FROM table1 t1
UNION ALL
SELECT t2."Id"
FROM table2 t2) t3
CROSS JOIN LATERAL regexp_split_to_table(t3."Id"::character varying, '') s(d)
GROUP BY s.d
ORDER BY s.d;
easiest way
select regexp_split_to_table(t3."Id"::character varying,'') s, count(*) count
from (select t1."Id" from table1 t1 union all select t2."Id"from table2 t2) t3
group by s

How to make a proper cross join

I want to cross join the two table
Query
Select * from table1 cross join select * from table2
Above query is showing error.
What wrong in my query
Reference
The result set of the Cross Join is the number of rows in the first table multiplied by the number of rows in the second table
SELECT T1.Columns1, T1.Column2, T2.ColumnName FROM Table1 T1
CROSS JOIN Table2 t2
You must use select like this : SELECT T1.FIELD1, T2.FIELD2 FROM TABLE1 AS T1 CROSS JOIN TABLE2 AS T2 - FIELD[X] FOR EXAMPLE ONLY
Try this:
SELECT * FROM table1, table2
or this:
select * from table1 CROSS JOIN table2;

Inverted SQL query

I've got the following tables:
Table1 {ArticleNo (int), ArtDescription (string) }
Table2 { ArticleNo (int), Year (date) }
Table1.ArticleNo is a primary key.
Table2.ArticleNo is a foreign key referenced to table1.ArticleNo
It's difficult to explain what I want to query, so here a short example:
Table1
(1,Desk)
(2,Chair)
(3,Ruler)
Table2
(1,2000)
(1,2000)
(2,2001)
The query should return:
1 Desk 2001
2 Chair 2000
3 Ruler 2000
3 Ruler 2001
All articles which are not sold (or whatever) in all years (all years from table2).
I hope you understand my example - the query seems to be very complex. Here my approach to a solution:
SELECT table1.ArticleNo,table1.ArtDescription,table2.Year
FROM table1
JOIN table2
ON table1.ArticleNo=table2.ArticleNo
WHERE NOT table1.ArticleNo IN (SELECT table2.Year FROM table2);
I tried lots of different things.. I hope you can help me!
SELECT t1.*, t2.year
FROM t1
CROSS JOIN
(
SELECT DISTINCT year
FROM t2
) t2
WHERE (t1.id, t2.year) NOT IN
(
SELECT t2.id, t2.year
FROM t2
)
Create an index on t2 (year, id) (in this order) for the query to work fast.
You could use a cross join to create a list of all item+year combinations. Then you could filter the rows without sales with a not exists condition:
select *
from t1 items1
cross join
(
select distinct year
from t2 sales1
) sales2
where not exists
(
select *
from t2 sales3
where sales3.ItemId = items1.ItemId
and sales3.Year = sales2.Year
)
There are a bunch of ways of doing this. Two examples:
select
t1.ArtDescription,
y.Year
from
Table1 t1
join (
select distinct
t2.Year
from
Table2 t2
) y on 1=1
where
not exists (
select
1
from
Table2 tx2
where
tx2.ArticleNo = t1.ArticleNo and tx2.Year = y.Year)
Oracle (SQL Server can do the same thing, use EXCEPT instead of MINUS):
select
t1.ArtDescription,
y.Year
from
Table1 t1
join (
select distinct
t2.Year
from
Table2 t2
) y on 1=1
MINUS
select
t12.ArtDescription
t22.Year
from
Table1 t12
join Table2 t22 on t12.ArticleNo = t22.ArticleNo
SELECT DISTINCT table1.ArticleNo,table1.ArtDescription,table2.Year
FROM table1 CROSS JOIN table2
WHERE table1.ArticleNo != table2.ArticleNo order by table1.ArticleNo;