SQL Query using inner join with a subquery which 0 line - sql

In my query, I select a column which cannot exist because this column comes from a subquery in a join. (The subquery can give me 0 lines)
Consequently, in this case, I want to select 0 instead of "temp.Quantity" column.
The code:
SELECT
bx.BX_BoxNum,
temp.Quantity -- <- this column
FROM BOX bx
INNER JOIN (SELECT BX_Id, SUM(BX_Quantity) AS Quantity FROM BOX
WHERE BX_Top_S = 'True' GROUP BY BX_Id) temp
ON bx.BX_Id = temp.BX_Id
WHERE bx.BX_BoxNum = 10
Sometimes a box number is empty! And I try to have a line with "BOX n°10 -- 0" instead of nothing
Could you please help me?

SELECT bx.BX_BoxNum, ISNULL(temp.Quantity, 0)
FROM BOX bx
left outer JOIN (SELECT BX_Id, SUM(BX_Quantity) AS Quantity FROM BOX
WHERE BX_Top_S = 'True' GROUP BY BX_Id) temp ON bx.BX_Id = temp.BX_Id
WHERE bx.BX_BoxNum = 10
Outer joins allow selects to happen when one side of a join returns nothing. Inner Joins have to have rows on both sides of the join (as you've found!). Google for the differences between LEFT, RIGHT and FULL Outer joins.

SELECT bx.BX_BoxNum, SUM(COALESCE(temp.Quantity, 0)) AS Quantity
FROM BOX bx
LEFT JOIN BOX temp ON bx.BX_Id = temp.BX_Id AND temp.BX_Top_S = 'True'
WHERE bx.BX_BoxNum = 10
GROUP BY bx.BX_BoxNum

Related

Why Hive SQL returning NULL values for a particular column in Select statement when that column has all double values?

I'm using Hive SQL. Version is Hive 1.1.0-cdh5.14.0. In my example below, sp.close is a column with type double values. I checked sp.column and there are definitely no NULL values. Yet, in this select statement below, sp.close shows all NULL values. Why?
select
step1.*,
sp.close
from
step1 left join stockprices2 sp on (
step1.symbol = sp.symbol and
step1.year = sp.year and
step1.startmonth = sp.month and
step1.startday = sp.day and
step1.sector = sp.sector
)
;
Most likely, your left join did not find a matchin row in stockprices2. In that event, the row from step1 is retained, but all columns from stockprices2 will be null in the resultset. This is by design how the database signals that the left join came up empty.
You can easily verify that by just chaning the left join to an inner join: you should have less rows returned (where there is no match in stockprices2, the row from step1 is removed from the resultset), and no null values in sp.close.
Or you can add one of the columns used in the left join conditions in the select clause, and see that it's null too.
select
st.*,
sp.close,
sp.symbol -- null too
from step1 st
left join stockprices2 sp
on st.symbol = sp.symbol
and st.year = sp.year
and st.startmonth = sp.month
and st.startday = sp.day
and st.sector = sp.sector
Side note: the parentheses around the join conditions are superfluous.

How do I condition a HAVING query?

I have the following query:
select ctc.sentencia ,count(lg.id_libro) as cantidad
from cat_tipo_sentencia as ctc
left join libro_gobierno as lg on lg.cod_tiposentencia = ctc.id_sentencia
left join expedientes as e on e.id_expedientes = lg.cod_expediente
GROUP BY ctc.sentencia
I want to count the records that are in "libro_gobierno" of "cat_tipo_sentencia", but when conditioned it does not show me those that have 0 records and when removing the condition if it shows them, how could I condition so that the results return those that do not have records?
-
this is the conditioned query
select ctc.sentencia ,count(lg.id_libro) as cantidad
from cat_tipo_sentencia as ctc
left join libro_gobierno as lg on lg.cod_tiposentencia = ctc.id_sentencia
left join expedientes as e on e.id_expedientes = lg.cod_expediente
where e.cod_distrito= 130
and e.cod_estado_pro=13
and ctc.id_sentencia in (1,8,10)
GROUP BY ctc.sentencia
and when trying to use "HAVING" I get an error since the conditions are not within the group
these are the data that throws me
sentencia1 1
but in my condition there are also other options but it does not show them to me because there are no records, and I would like it to return me similar to:
sentencia1 1
sentencia2 0
sentencia3 0
PD: Sorry for the English, I'm using translator :(
In a LEFT OUTER JOIN, if you filter the outer table in the WHERE clause, the results become the same as if you did an INNER join. Rows from the main table that don't have a match in the joined table are filtered off.
You can avoid this by filtering in the ON clause of your join, instead of in the WHERE clause.
SELECT
ctc.sentencia
,count(lg.id_libro) AS cantidad
FROM
cat_tipo_sentencia AS ctc
LEFT JOIN
libro_gobierno AS lg
ON lg.cod_tiposentencia = ctc.id_sentencia
LEFT JOIN
expedientes AS e
ON e.id_expedientes = lg.cod_expediente
AND e.cod_distrito = 130
AND e.cod_estado_pro = 13
WHERE
ctc.id_sentencia IN (1,8,10)
GROUP BY
ctc.sentencia
I tried to use common words. I hope this translates OK for you!

Join based on case statement

I want to have 2 join condition between two tables, first join condition should work always but the second Join condition should work only if condition is satisfied other wise give the result based on first two join.
I have two way one is directly give two condition and then add case statement
for third join
second I tried to have case statement after ON For first case I had 1 join condition and for second case 2 put 2 Join Condition.
SELECT *,IND.bill_to_id FROM txn_sales_shippedorders_intl shippedorders
LEFT JOIN ( SELECT cust_sid, max(cust_key) cust_key
,cust_nbr
FROM com_hub.ref_customer_hco_intl
GROUP BY cust_sid, cust_nbr
) cust ON cust.cust_sid = regexp_replace(shippedorders.cust_align_sid, "\\.0*", '')
--AND cust.country_cd = shippedorders.country_cd
AND cust.src_sys_id=shippedorders.src_sys_id
LEFT JOIN
(SELECT CUSTOMER,ship_to_id, bill_to_id
FROM com_lake.ref_india_customer_crossmap
) ind ON case when substr(SDVR02,1,2) ='IM'
and ind.ship_to_id = cust.cust_nbr then 1
WHEN substr(SDVR02,1,2) ='ER' and ind.CUSTOMER = cust.cust_name then 1
else 0
end 1
At the moment your join doesn't make sense. You have to look at the result of your case statement.
At the moment it reads:
Left JOIN (...) ind ON 0
or
Left Join (...) ind on 1
You need to have an argument - e.g.
Left JOIN (...) ind on ind.index = CASE WHEN ...

Left outer join with 2 column missing some output rows

When I select all rows from table zvw_test it return 145 rows.
Table Customer_Class_Price have 160 rows.
When I try to join this 2 table with 2 condition it return 122 rows.
I don't understand why it not return all rows from zvw_test (145 rows)
becasue I use left outer join it should return all rows from left table.
Thank you.
SELECT zvw_test.Goods_ID,
zvw_test.Thai_Name,
zvw_test.UM,
zvw_test.CBal,
Customer_Class_Price.ListPrice
FROM zvw_test
LEFT OUTER JOIN
Customer_Class_Price ON zvw_test.Goods_ID = Customer_Class_Price.Goods_ID AND
zvw_test.UM = Customer_Class_Price.UM
WHERE (Customer_Class_Price.ClassCode = '444-666')
By putting one of your columns from the LEFT OUTER JOIN table in your WHERE clause, you have effectively turned it into an INNER JOIN. You need to move that up to the JOIN clause.
I had this problem before, I used a CTE to solve this, like:
WITH A AS
(
SELECT Customer_Class_Price.Goods_ID, Customer_Class_Price.UM, Customer_Class_Price.ListPrice
FROM Customer_Class_Price
WHERE Customer_Class_Price.ClassCode = '444-666'
)
SELECT zvw_test.Goods_ID, zvw_test.Thai_Name, zvw_test.UM, zvw_test.CBal, A.ListPrice
FROM zvw_test LEFT OUTER JOIN A
ON zvw_test.Goods_ID = A.Goods_ID AND zvw_test.UM = A.UM
You demand in your WHERE clause:
(Customer_Class_Price.ClassCode = '444-666')
Ergo you are not selecting rows where Customer_Class_Price.ClassCode IS NULL. Customer_Class_Price.ClassCode would be NULL if there is no corresponding row, but you are filtering those out explicitely.

when use order by i get "Divide by zero error encountered."

I have the following SQL Query which works if I remove the last line which is order by.
Can anyone tell me please why this is not working when I put order by on this query.
declare #UQ as decimal(20,6);
declare #MUQ as decimal(20,6);
select #UQ=ItemUnit_UnitQuantity, #MUQ=ItemUnit_MainUnitQuantity from tItemUnit
where ItemUnit_Id = 23996
select top 1 (InvBuyPriceValue/InvL_Quantity)*iu.ItemUnit_UnitQuantity/iu.ItemUnit_MainUnitQuantity*#MUQ/#UQ as InvBuyPrice, Discount
from tInvL l
left outer join tInvH h on h.InvH_Id = l.InvH_Id
left outer join tItem i on i.Item_Id = l.Item_Id
left outer join tItemUnit iu on iu.ItemUnit_Id = l.ItemUnit_Id
left outer join tUnit u on u.Unit_Id = iu.Unit_Id
left outer join tClientObj clo on clo.ClientObj_Id = h.ClientObj_Id
left outer join tDocType dt on dt.DocType_Id = h.DocType_Id
where h.CompanyObj_Id = (select CompanyObj_Id from tEnabledCompany where CompanyClientObj_Id=(select ClientObj_Id from tClientObj where ClientObj_Code = '504'))
and dt.DocType_InOut = 1
and l.Item_Id = 19558
and h.ClientObj_Id = 386
order by InvH_DocDate desc, InvH_DocTime desc
I get the error saying:
Divide by zero error encountered.
I don't understand why I get this error on order by and not for example in select statement...
There are divisions in
select top 1 (InvBuyPriceValue/InvL_Quantity)*iu.ItemUnit_UnitQuantity/iu.ItemUnit_MainUnitQuantity*#MUQ/#UQ
so probably InvL_Quantity or iu.ItemUnit_MainUnitQuantity are zero.
Why don't you see the SQL Server error without the ORDER BY? You are only requesting the TOP 1 row, so the SQL Server does not need to go over all rows and calculate the result. For performance reasons the SQL Server just picks the TOP 1 row, calculates the results for it and returns it.
That you get a divide-by-zero with TOP 1 and not without is just by chance. You'll definitely see the same error if you don't TOP 1 and if you don't ORDER BY.
SELECT TOP 1
(InvBuyPriceValue / InvL_Quantity) *
iu.ItemUnit_UnitQuantity / iu.ItemUnit_MainUnitQuantity *
#MUQ / #UQ AS InvBuyPrice,
That is the only place where you are performing divisions. Either InvL_Quantity or ItemUnit_MainUnitQuantity columns might contain the value zero.
Also check ItemUnit_UnitQuantity, which is the value being assigned to #UQ, which is also a divisor.