Group by day and left outer join the whole - sql

The data like
mdn day flag
c 20180302 0
c 20180303 1
b 20180303 0
a 20180301 1
b 20180301 0
a 20180302 1
I get the whole by select distinct mdn from data, and left join every day, how to realize it by using hive? As following, it's only one day sample:
with temp as (select distinct mdn from data)
select * from temp b
left outer join
(select * from data where day=20180302) a
on a.mdn=b.mdn
The result of one day like:
c c 20180302 0
a a 20180302 1
b null null null
Exactly, it is just one day, and I want to get 'b null 20180302 null'

Use a cross join to generate all the combinations:
select m.mdn, d.day, data.flag
from (select distinct mdn from data) m cross join
(select distinct day from data) d left join
data
on data.mdn = m.mdn and data.day = d.day ;

Related

Left join oracle db

I have two tables and I wanna join them (outer).
day description
-----
1 mo
2 tu
...
5 fr
order day code
----
1 1 0
2 2 0
3 1 2
4 3 0
5 4 0
I wanna this table as a result:
description order code
------
mo 1 0
th 2 0
we 4 0
tu 5 0
fr null null
When I use a left join like this, the code does not work right and does not show me friday:
select *
from days d left join order o on d.id= o.day
where o.code = 0
But when I write the code like this, the code works right:
select *
from
(select * from day) d
left join
(select * from order when code = 0) o
on d.id = o.day
Does anyone know why?
Just put the condition on the left joined table in the on clause of the left join rather than in the where clause:
select d.description, o.order, o.code
from days d
left join order o on d.id= o.day and o.code = 0
Conditions in the where clause are mandatory - so the where clause eliminates rows where the left join came back empty, since o.code is null, which is not equal to 0.
on condition is used to join the table.
where condition is to filter the records from the join result.
Below will join the table on the condition of d.id = o.day
and then select records only with o.code=0
select *
from days d left join order o on d.id= o.day
where o.code = 0
In order to join on both d.id = o.day and o.code=0
you need below
select *
from days d left join order o on d.id= o.day
and o.code = 0

SQL query to identify rows not contained contained in another table across multiple subsets

I have two tables as seen below.
Table 1:
Day Group
---------
1 A
1 B
1 C
2 B
2 C
2 D
3 C
3 D
3 E
Table 2:
Group
-------
A
B
C
D
E
I would like to create a SQL query that identifies each Group that exists in Table 2 but does not exist in Table 1 partitioned by Day.
The desired result would look like this:
Day Group
---------
1 D
1 E
2 A
2 E
3 A
3 B
Use a cross join to generate all combinations and then weed out what you have:
select d.day, t1.group
from (select distinct day from table1) d cross join
table2 g left join
table1 t1
on t1.day = d.day and t1.group = g.group
where t1.day is null;
SELECT
*
FROM
(
SELECT DISTINCT
Day
FROM
Table1
) AS Days
,
Table2
WHERE
NOT EXISTS (
SELECT
*
FROM
Table1
WHERE
Table1.day=Days.Day AND
Table1.Group=Table2.Group
)

SQL Server, selecting from 2 columns from different tables

I have these columns from 2 tables
Table1 Table2
Code ID Code ID
A 1 A 1
B 1 B 1
C 1 C 1
D 1
E 1
My query:
Select
a.id, a.code, b.code
from
Table1 a, Table2 b
where
a.id = '1' and a.id = b.id
What I expected
ID code code
1 A A
1 B B
1 C C
1 D NULL
1 E NULL
What I got
ID code code
1 A A
1 B A
1 C A
1 D A
1 E A
1 A B
1 B B
1 C B
....
Any ideas? distinct didn't help
Thanks
Well, all the ID's in both tables are 1, so by joining on ID you'll get the cartesian product of both tables.
Instead, you'll need to do a left outer join based on Table1.Code:
Select a.id, a.code, b.code
from Table1 a LEFT OUTER JOIN Table2 b
on a.code = b.code
where a.id = '1';
You need to do a LEFT OUTER JOIN instead of a Cartesian Product
SELECT a.Id, a.Code, b.Code FROM Table1 a
LEFT OUTER JOIN Table2 b ON a.Code = b.Code
WHERE a.Id = '1'
A LEFT OUTER JOIN returns all rows from the left-hand side of the join (in this case Table 1) regardless of whether there is a matching record in the table on the right-hand side of the join (in this case Table 2). Where there is no match a NULL is returned for b.Code as per your requirements.
Reference OUTER JOINS

T-SQL split row into multiple rows?

I have the table in sql db like this.
Category Series Value
1 A 100
2 B 200
2 C 300
How do I select to project like this?
Category Series Value
1 A 100
1 B 0
1 C 0
2 A 0
2 B 200
2 C 300
In order to get the result, you will want to generate a list of all categories with each series. You can use a CROSS JOIN to get the result:
select distinct c.category, s.series
from yourtable s
cross join yourtable c
Once you have this, then you can join this back to your table on both the category and series:
select sc.category,
sc.series,
coalesce(t.value, 0) value
from
(
select distinct c.category, s.series
from yourtable s
cross join yourtable c
) sc
left join yourtable t
on sc.series = t.series
and sc.category = t.category;
See SQL Fiddle with Demo

How to get this result with and only with SQL?

The question is:
Two tables (t1, t2)
Table t1:
SELLER | NON_SELLER
A B
A C
A D
B A
B C
B D
C A
C B
C D
D A
D B
D C
Table t2:
SELLER | COUPON | BAL
A 9 100
B 9 200
C 9 300
D 9 400
A 9.5 100
B 9.5 20
A 10 80
Using SELECT Statement to get this result:
SELLER| COUPON | SUM(BAL)
A 9 900
B 9 800
C 9 700
D 9 600
A 9.5 20
B 9.5 100
C 9.5 120
D 9.5 120
A 10 0 # !!!
B 10 80
C 10 80
D 10 80
For seller A SUM(BAL) means sum( B.BAL,C.BAL,D.BAL), for B, SUM(BAL)=SUM(A.BAL,C.BAL,D.BAL)...
Please find a way with good performance and don't use temporary table.
My solution:
Running this query will get the result but without the row "A 10 0":
select t1.seller, t2.coupon, sum(bal)
from t1, t2
where t1.non_seller = t2.seller
group by t1.seller, t2.coupon
order by t2.coupon
Please help ~~~~~~
If I understand you correctly, you're looking for data on all sellers and all coupons. So let's start with a cross join that generates a list of coupons and sellers:
select sellers.seller
, coupons.coupon
from (
select distinct seller
from Table2
) as sellers
cross join
(
select distinct coupon
from Table2
) as coupons
For each seller-coupon combination, you're looking for the sum they can buy from other sellers. This can be accomplished by a left join:
select sellers.seller
, coupons.coupon
, case when sum(t2.bal) is null then 0 else sum(t2.bal) end
from (
select distinct seller
from Table2
) as sellers
cross join
(
select distinct coupon
from Table2
) as coupons
left join
Table2 t2
on t2.seller <> sellers.seller
and t2.coupon = coupons.coupon
group by
sellers.seller
, coupons.coupon
The only function of the case statement is to replace a null sum with a 0.
The output matches the one in your answer. Note that this solution doesn't use Table1: the list of other sellers is produced by the t2.seller <> sellers.seller condition in the left join.
I get another way to this:
select t1.seller, t2.coupon, sum(bal)
from t1, t2
where t1.non_seller = t2.seller
group by t1.seller, t2.coupon
union
(select seller,coupon,0 from t2 group by coupon having count(seller) == 1);
And I don't know if it is better or worst than compare with #Andomar :
select sellers.seller
, coupons.coupon
, case when sum(t2.bal) is null then 0 else sum(t2.bal) end
from (
select distinct seller
from Table2
) as sellers
cross join
(
select distinct coupon
from Table2
) as coupons
left join
Table2 t2
on t2.seller <> sellers.seller
and t2.coupon = coupons.coupon
group by
sellers.seller
, coupons.coupon