Trying to use a self join in SQL to look up a value in the table and apply it.
Her's what I got:
+-----------------+-----+--------+-----------+
| Acutal Output | | | |
+-----------------+-----+--------+-----------+
| TRKID | Fac | NewFac | BAG_TRKID |
| 449 | 11 | 11 | 999 |
| 473 | 11 | 11 | 737 |
| 477 | 11 | 11 | 737 |
| 482 | 11 | 11 | 737 |
| 737 | 89 | 89 | |
| Desired Out Put | | | |
| TRKID | Fac | NewFac | BAG_TRKID |
| 449 | 11 | 11 | 999 |
| 473 | 11 | 89 | 737 |
| 477 | 11 | 89 | 737 |
| 482 | 11 | 89 | 737 |
| 737 | 89 | 89 | |
+-----------------+-----+--------+-----------+
Here's the code below. I can't seem to get the table that I want. The Bag TrkID's Facility Num is not becoming the TrkID New Facility Num.
Select
TABLEA.TRKID,
TABLEA.FAC,
NVL(TABLEA.FAC, TABLEB.FAC) as NEWFAC,
TABLEA.BAG_TRKID
FROM
(
Select
HSD. TRKID,
HSD.NLPT as FAC,
SBPD.BAG_TRKID
From
HSD
LEFT JOIN
SBPD
ON
SBPD.BAG_TRKID = HSD. TRKID
Where
HSD.SCANDT BETWEEN ‘Yesterday’ and ‘Today’
) TABLEA
LEFT JOIN
(
Select
HSD. TRKID,
HSD.NLPT as FAC,
SBPD.BAG_TRKID
From
HSD
LEFT JOIN
SBPD
ON
SBPD.BAG_TRKID = HSD. TRKID
Where
HSD.SCANDT BETWEEN ‘Yesterday’ and ‘Today’
) TABLEB
ON
TABLEA.TRKID = TABLEB.BAG_TRKID
Perhaps something like
select a.TrkID, a."Facility Number", a.BAG_TRKID, b.TrkID as "NEW Fac"
from tbl a
left join tbl b on (a.TrkID = b.trk_id_reference)
Given the limited information that you've shared, I was able to achieve the expected output with the following query:
SELECT a.TrkID, a.facility_number, a.bag_trkid, b.facility_number as new_facility_number
FROM test_tbl AS a
LEFT JOIN test_tbl AS b ON a.bag_trkid = b.trkid OR (a.bag_trkid IS NULL AND b.trkid = a.trkid);
You want to get the new_facility_number for a row based on its bag_trkid (which can be achieved by this: LEFT JOIN test_tbl AS b ON a.bag_trkid = b.trkid).
BUT the trick is to account for the cases when the Left Table (which I refer as a) does not have a bag_trkid. In this case, we will keep the new_facility_number to be the same as a.facility_number, joining the tables on the trkid solely: OR (a.bag_trkid IS NULL AND b.trkid = a.trkid)
Related
I need some help, I looked for a solution in other posts but I couldn't make those solutions work.
I have a table that contains a bunch of id's...
table1
customerId | adsId | campaignId | contextId | Date | amoutDue
------------------------------------------------------------------------
1234341233 | 4r4w3 | cp123sifs | cbgvss23r23dd | 03-09-2021 | 50
4556666666 | 35533 | cp453f44f | cb2d3d23dd33d | 04-06-2021 | 25
3444468766 | 12345 | cpef4f44r | ccascasca333s | 23-04-2021 | 13
6346522452 | qw324 | cpfe4r333 | c23ddsasssd2f | 12-07-2021 | 71
3463466346 | 23423 | cp1vt5rfr | kjhcbwiytcubp | 25-02-2021 | 41
4534634346 | 534f3 | cp4343ff4 | apisuchha9shh | 14-05-2021 | 36
7743646346 | wer32 | cp4ffwefe | cq98hd98ladse | 12-03-2021 | 53
2424233335 | r4w4r | cpwerewff | q09jucidnionc | 05-06-2021 | 65
In another table I have the adsId and adsName:
table2(adsId/adsName)
adsName | adsId
--------------------
ad-google1 | 4r4w3
ad-fbtests | 35533
ad-bingpro | 12345
ad-maillan | qw324
ad-cp-e312 | 23423
ad-gads2-4 | 534f3
ad-adProsk | wer32
ad-cpcB151 | r4w4r
On the 3rd table I have campaingName and campaingId:
table3(campaingId/campaignName)
campaignName | campaignId
------------------------
cp-adWords | cp123sifs
cp-looki12 | cp453f44f
cp-cvccp53 | cpef4f44r
cp-Pliiltr | cpfe4r333
cp-Yellinf | cp1vt5rfr
cp-Iuliucs | cp4343ff4
cp-Ieventx | cp4ffwefe
cp-Shoofab | cpwerewff
Finally the 4th table I have contextId and contextName:
table4(contextId/contextName)
contextId | contextName
-----------------------------
cbgvss23r23dd | ctx-Okkels
cb2d3d23dd33d | ctx-Yumeis
ccascasca333s | ctx-Niehok
c23ddsasssd2f | ctx-Sluiru
kjhcbwiytcubp | ctx-Strogi
apisuchha9shh | ctx-Slucha
cq98hd98ladse | ctx-Epuent
q09jucidnionc | ctx-Igeegs
What I'm looking for is the 5th table that gets all names from other tables (that contains the id's) and give the names:
table5
customerId | adsId | campaignId | contextId | Date | amoutDue | adsName |campaignName| contextName
---------------------------------------------------------------------------------------------------------------------
1234341233 | 4r4w3 | cp123sifs | cbgvss23r23dd | 03-09-2021 | 50 | ad-google1 | cp-adWords | ctx-Okkels
4556666666 | 35533 | cp453f44f | cb2d3d23dd33d | 04-06-2021 | 25 | ad-fbtests | cp-looki12 | ctx-Yumeis
3444468766 | 12345 | cpef4f44r | ccascasca333s | 23-04-2021 | 13 | ad-bingpro | cp-cvccp53 | ctx-Niehok
6346522452 | qw324 | cpfe4r333 | c23ddsasssd2f | 12-07-2021 | 71 | ad-maillan | cp-Pliiltr | ctx-Sluiru
3463466346 | 23423 | cp1vt5rfr | kjhcbwiytcubp | 25-02-2021 | 41 | ad-cp-e312 | cp-Yellinf | ctx-Strogi
4534634346 | 534f3 | cp4343ff4 | apisuchha9shh | 14-05-2021 | 36 | ad-gads2-4 | cp-Iuliucs | ctx-Slucha
7743646346 | wer32 | cp4ffwefe | cq98hd98ladse | 12-03-2021 | 53 | ad-adProsk | cp-Ieventx | ctx-Epuent
2424233335 | r4w4r | cpwerewff | q09jucidnionc | 05-06-2021 | 65 | ad-cpcB151 | cp-Shoofab | ctx-Igeegs
I tried to use join but I couldn't select all tables... My SQL in words would be:
get campaingName from table 2 and create a row with the name where campaingId from table1 = to campaingId from table 2 the same for all fields...
Thanks in advance!
You would use join like this
select *
from table1 t1 join
table2 t2
using (adsid) join
table3 t3
using (campaignid) join
table4 t4
using (contextid);
The above works because the join keys have the same names in the reference table and the original table (a best practice). You can also use the more verbose:
select t1.*, t2.adsName, t3.campaignName, t4.contextName
from table1 t1 join
table2 t2
on t2.adsid = t1.adsid join
table3 t3
on t3.campaignid = t1.campaignid join
table4 t4
on t4.contextid = t1.contextid;
If some of the ids are missing, then use left join instead of join.
you can use multiple with clause within big query to achieve this.
WITH TEST1 AS
(select a1.*,a2.adsName
from `<project_name.<dataset_name>.table1` a1, `<project_name.<dataset_name>.table2` a2
where a1.adsId=a2.adsId),
TEST2 as
(
select TEST1.*,a3.campaignName
from TEST1, `<project_name.<dataset_name>.table3` a3
WHERE TEST1.campaignId=a3.campaignId)
select TEST2.*, a4.contextName
from TEST2,`<project_name.<dataset_name>.table4` a4
WHERE TEST2.contextId=a4.contextId
All, so I am trying to run the query.
The query consist of 7 tables and I want to all table get left joined based on A.conn_keyy and the others with clause 'ON'
My confusion comes when I want to join CPLCUR based on A , not works.
(CPLCUR.conn_keyy in ( a.conn_keyy = b.conn_keyy )
It appears error :
both left and right aliases encountered in join 'conn_key'
set hive.support.quoted.identifiers=none;
select
coalesce(a.conn_keyy, b.conn_keyy,CPLCUR.conn_keyy) as rrconn_keyy,
b.rfbbn, b.LINES_ID,b.TYPE,CPLCUR.*
FROM
(tablee.aa)A
LEFT OUTER JOIN
(tablee.bb) B
ON (A.conn_keyy = B.conn_keyy)
LEFT OUTER JOIN (SELECT `(c21)?+.+` FROM tablee.cc ) CPLCUR
ON (CPLCUR.conn_keyy in ( a.conn_keyy = b.conn_keyy )
AND CPLCUR.cllt = REGEXP_EXTRACT(B.rfbbn,'^(?:[^*]*\\*){2}([^*]*)',1))
LEFT OUTER JOIN (SELECT DISTINCT * FROM tablee.dd) CPLBAL
ON CPLBAL.conn_keyy = A.conn_keyy
AND CPLBAL.SEQUENCE = CPLCUR.SEQUENCE
AND CPLBAL.dtdt = '1999'
LEFT OUTER JOIN
(tablee.REP)REP
ON REP.relino = B.lnido
LEFT OUTER JOIN tablee.P PRD
ON PRD.PRODUCT_CODE = REGEXP_EXTRACT(A.conn_keyy,'[.]([^.]+)',1)
AND PRD.dtdt = '1999'
WHERE B.lnido LIKE 'PLCONS1%'
) rrvv;
What is best practice to get this?
The desired results:
+-----------+---------+--------+----------+-------------+-------+-----+-----+
| conn_keyy | b.rfbbn | b.LINES| b.TYPE | CPLCUR | CPLBAL| REP | PRD |
+-----------+---------+--------+----------+-------------+-------+-----+-----+
| 111 | aaa | PCOS1% | bbsr | 2019-02-21 | | | |
| 200 | | PCOS1% | ny | X | | | |
| 222 | bbb | PCOS1% | pp | Y | | | |
| 300 | rrr | PCOS1% | atl | 2019-03-18 | | | |
| 333 | ccc | PCOS1% | dd | Z | | | |
| 400 | vvv | PCOS1% | tt | 2019-03-18 | | | |
+-----------+---------+--------+----------+-------------+-------+-----+-----+
I am trying to generate a report of every product sold of SKUABC in size 34 with inseam 33 (it is available in 33 and 31 inseam).
Table - orders_products
Table - Orders:
+-----------+------------------------+--+
| Orders_id | date_purchased | |
+-----------+------------------------+--+
| 46198 | 2020-10-18 19:43:25 | |
| 46199 | 2020-10-19 19:43:25 | |
| 46200 | 2020-10-22 19:43:25 | |
+-----------+------------------------+--+
Table - orders_products
+--------------------+-----------+-------------+----------------+--+
| orders_products_id | Orders_id | products_id | products_mode | QTY
+--------------------+-----------+-------------+----------------+--+
| 42154907 | 46198 | 878 | SKUABC |1 |
| 42154908 | 46198 | 878 | SKUABC |1 |
| 42154909 | 46198 | 282 | DIFFSKU |1 |
+--------------------+-----------+-------------+----------------+--+
Table - Orders_products_attributes (showing order_id 46198 only):
+------------------------------+-----------+--------------------+-----------------+-----------------------+--+
| orders_products_attribute_id | orders_id | orders_products_id | Product options | Product_options_value | |
+------------------------------+-----------+--------------------+-----------------+-----------------------+--+
| 167618 | 46198 | 42155189 | Color | Green | |
| 167619 | 46198 | 42155189 | Inseam | 33 | |
| 167620 | 46198 | 42155189 | Size | 34 | |
+------------------------------+-----------+--------------------+-----------------+-----------------------+--+
my sql so far:
SELECT distinct o.orders_id, op.products_model, opa.products_options_values, sum(op.products_quantity)
FROM orders o
LEFT JOIN orders_products op
ON o.orders_id = op.orders_id
LEFT JOIN orders_products_attributes opa
on op.orders_id = opa.orders_id
WHERE op.products_model in ('SKUABC')
and opa.`products_options_values` in ('36')
and o.date_purchased > '2020-10-13'
If I add in :
and opa.`products_options_values` in ('31')
it returns no results, the reason being because the inseam and size rows are separate. and the problem with the above code is that it is combining any orders/ordered products where the inseam is both 33 or 31 but I want it to be separate.
My desired out would be
+--------+------------+------------+-------------------+
| model | attribute1 | attribute2 | quantity sold sum |
+--------+------------+------------+-------------------+
| ABCSKU | 34 | 33 | 120 |
+--------+------------+------------+-------------------+
Here is a fun solution: select two products_options_values and label those in different name then everything will be easy
SELECT distinct o.orders_id, op.products_model, opa.products_options_values
AS Inseem,opa2.products_options_values AS Size, sum(op.products_quantity)
FROM orders o
LEFT JOIN orders_products op
ON o.orders_id = op.orders_id
LEFT JOIN orders_products_attributes opa
ON op.orders_id = opa.orders_id
LEFT JOIN orders_products_attributes opa2
ON op.orders_id = opa.orders_id
--your condition below
then just use opa for inseem and opa2 for size.It is stupid but work.You can even make the rows data null by adding some condition with Product option column for easier insert later.
I got rather complicated riddle to solve. So far I'm unlocky.
I got 3 tables which I need to join to get the result.
Most important is that I need highest h_id per p_id. h_id is uniqe entry in log history. And I need newest one for given point (p_id -> num).
Apart from that I need ext and name as well.
history
+----------------+---------+--------+
| h_id | p_id | str_id |
+----------------+---------+--------+
| 1 | 1 | 11 |
| 2 | 5 | 15 |
| 3 | 5 | 23 |
| 4 | 1 | 62 |
+----------------+---------+--------+
point
+----------------+---------+
| p_id | num |
+----------------+---------+
| 1 | 4564 |
| 5 | 3453 |
+----------------+---------+
street
+----------------+---------+-------------+
| str_id | ext | name |
+----------------+---------+-------------+
| 15 | | Mein st. 33 | - bad name
| 11 | | eck st. 42 | - bad name
| 62 | abc | Main st. 33 |
| 23 | efg | Back st. 42 |
+----------------+---------+-------------+
EXPECTED RESULT
+----------------+---------+-------------+-----+
| num | ext | name |h_id |
+----------------+---------+-------------+-----+
| 3453 | efg | Back st. 42 | 3 |
| 4564 | abc | Main st. 33 | 4 |
+----------------+---------+-------------+-----+
I'm using Oracle SQL. Tried using query below but result is not true.
SELECT num, max(name), max(ext), MAX(h_id) maxm FROM history
INNER JOIN street on street.str_id = history._str_id
INNER JOIN point on point.p_id = history.p_id
GROUP BY point.num
In Oracle, you can use keep:
SELECT p.num,
MAX(h.h_id) as maxm,
MAX(s.name) KEEP (DENSE_RANK FIRST ORDER BY h.h_id DESC) as name,
MAX(s.ext) KEEP (DENSE_RANK FIRST ORDER BY h.h_id DESC) as ext
FROM history h INNER JOIN
street s
ON s.str_id = h._str_id INNER JOIN
point p
ON p.p_id = h.p_id
GROUP BY p.num;
The keep syntax allows you to do "first()" and "last()" for aggregations.
I have 2 tables.
Table #1: orders
order_id | crit_1 | crit_2 | crit_3 | other
01 | A00 | GER | 49er | x
02 | A00 | GER | 49er | x
03 | A00 | USA | 49er | x
04 | C80 | DEN | 66er | x
05 | B50 | GER | 99er | x
The table orders has 3 important criteria but doesn't have the criterion_4. There is another table with the order_positions which contains multiple criterion_4 entries for each order_id.
Table #2: classifications
crit_1 | crit_2 | crit_3 | crit_4 | class_1 | class_2
A00 | GER | 49er | 4711 | A | 11
A00 | GER | 49er | 4712 | A | 21
A00 | USA | 49er | 4711 | D | 12
A00 | USA | 49er | 4712 | D | 21
B50 | GER | 99er | 4801 | B | 12
B50 | GER | 99er | 4802 | B | 12
B50 | GER | 99er | 4803 | B | 14
C80 | DEN | 66er | 4904 | C | 22
C80 | DEN | 66er | 4905 | C | 21
The table classifications contains classifications for:
orders = class_1 = combination of crit_1, crit_2 & crit_3
order_positions = class_2 = combination of crit_1, crit_2, crit_3
& crit_4
I have a query where I join classifications.class_1 on the table orders to create a list of all orders and their respective classification.
select
orders.order_id,
orders.crit_1,
orders.crit_2,
orders.crit_3,
classifications.class_1
from
orders
left join
classifications
on
orders.crit_1=classifications.crit_1 and
orders.crit_2=classifications.crit_2 and
orders.crit_3=classifications.crit_3
where
orders.others = "..."
group by
orders.order_id,
orders.crit_1,
orders.crit_2,
orders.crit_3,
classifications.class_1
I need a GROUP BY at the end since the table classifications contains multiple entries with the combination of crit_1, crit_2 and crit_3. But this isn't a problem since the needed classification_1 is always the same for each combination of crit_1, crit_2 and crit_3.
Now I want to create another query where I count just the number of each classification_1 for the orders. Something like this:
class_1 | number
A | 12
B | 5
C | 18
. | .
But I don't know how without the whole selection of orders.order_id, orders.crit_1, orders.crit_2, orders.crit_3 and classifications.class_1
I just want to count the class_1 classifications for the query above.
Any suggestions?
edit
I tried it like suggested by Kaushik Nayak:
select
--orders.order_id,
--orders.crit_1,
--orders.crit_2,
--orders.crit_3,
classifications.class_1,
count(*)
from
orders
left join
classifications
on
orders.crit_1=classifications.crit_1 and
orders.crit_2=classifications.crit_2 and
orders.crit_3=classifications.crit_3
where
orders.others = "..."
group by
--orders.order_id,
--orders.crit_1,
--orders.crit_2,
--orders.crit_3,
classifications.class_1
But the results are not correct and I have no idea how to reproduce those numbers.
A few examples:
| class_1 | query w/ | query w/o | query |
| | group by | group by | count(*) |
---------------------------------------------
| A | 654 | 2179 | 1024 |
| B | 371 | 1940 | 667 |
| C | 94 | 238 | 247 |
When I use my query with group by then I get 654 entries for class_1 = A.
When I make my query without group bythen I get 2179 entries for class_1= A.
And when I try the query with Count(*) then I get 1024 entries for class_1 = A.
The last one is definitely not correct.
Just use GROUP BY class_1 for your classifications table and add an EXISTS condition to check if there is an order.
SELECT
c.class_1,
COUNT(c.class_1) "number"
FROM
classifications c
WHERE
EXISTS (
SELECT
1
FROM
orders o
WHERE
o.crit_1 = c.crit_1
AND o.crit_2 = c.crit_2
AND o.crit_3 = c.crit_3
)
GROUP BY
c.class_1
ORDER BY
1;