A SQL case statement or two - sql

I have a SELECT statement that pulls these two different product strips. When I delete one of them from the website and rerun my statement I still have two rows, the first column has the ARMCODE twice (two results) and the second column has the description for the first but then no description for the second (because it has been deleted).
Problem is it's still showing two results in SQL studio with the ARMCODE.
If there is a a.CODE_,a.strips from intake it needs to show, if there is an A.ARMCODE and B.DESCRIPTION it needs to show. If there is only A.ARMCODE and B.DESCRIPTION and the other has been deleted why is it still showing two results with a.CODE_ being the second result and an empty a.strips.
select a.ARMCODE,
b.DESCRIPTION_
from ARE.AAS.REORDER a
left outer join ARE.AAS.PTDME b on a.PTCODE=b.CODE_
where a.ARMCODE = 'ADSMANZS03'
and b.MEDICAREID ='A4253'
union all
select a.CODE_,a.strips
from event.dbo.intake a
where a.CODE_ = 'ADSMANZS03'
I started on a new statement using case and am now using some nested joins:
select case when b.ARMCODE is null then a.strips
end
from (select *
from ev.dbo.intake a
where a.CODE_ = 'ADSMANZS03') a
left outer join(select a.ARMCODE,
b.DESCRIPTION_
from ARE.AAS.REORDER a
left outer join ARE.AAS.PTDME b on a.PTCODE=b.CODE_
where a.ARMCODE = 'ADSMANZS03'
and b.MEDICAREID ='A4253') b on a.CODE_=b.ARMCODE
I'm not getting any rows or columns and it's returning (no column name) and inside NULL
Hope that is not too confusing. Thanks in advance.
IMAGE 1 Strips and description, two different products, same patient
IMAGE 2 When i delete strips, still showing two results with empty description, should not show a second result.
IMAGE 3 case statement

Just an fyi so this question can be closed. I used coalesce to determine what i needed.
select
coalesce(b.DESCRIPTION_,a.strips)
from(
select
*
from ev.dbo.intake a
where a.CODE_ = 'ADSMANZS03'
)a
left outer join(
select
a.ARMCODE,
b.DESCRIPTION_
from ARE.AAS.REORDER a
left outer join ARE.AAS.PTDME b on a.PTCODE=b.CODE_
where a.ARMCODE = 'ADSMANZS03'
and b.MEDICAREID ='A4253'
)b on a.CODE_=b.ARMCODE
COALESCE (Transact-SQL)
http://msdn.microsoft.com/en-us/library/ms190349.aspx

Related

When a column has a certain string, i want to replace it with a string from my left join

I was wondering if anyone could help. I want my main table to keep the meter records in my main table and when i get 'Others' i want these to be replaced by the left join tables.
The issue is when im doing my case when, my result is coming back as null?
The thing is with the data im left joining too it has a lot of other data that i have to filter and a join on with which might make this question a bit more complicated. First of all i just want to make sure my case when is working correctly before i do anymore testing.
Thanks!
WITH CTE_MAIN AS (
SELECT DISTINCT
EX.Meter,
CASE WHEN (EX.Metermodel) = 'Other'
THEN OJ.Metermodel
ELSE EX.Metermodel
END AS MeterModelRemoved
FROM `MAINTABLE` AS EX
LEFT JOIN `LEFTTABLE` AS OJ ON EX.METER=OJ.METER)
SELECT * #Test
FROM CTE_MAIN
WHERE Meter = 'G4A50027940101'
Main Table
METER
Metermodel
G4A50027940101
Other
000807612
Other
L0117797762M
Other
009X091
U6
5046314S
G4
Left join table
METER
Metermodel
G4A50027940101
U6
000807612
G4
L0117797762M
G4
009X091
U6
5046314S
LPG
Result: MeterModelRemoved = null
Few more options:
In case if both tables have exact same structure (as it is in your question) - consider below approach
select if(t1.Metermodel = 'Other', t2, t1).*
from MainTable t1
left join LeftTable t2
using(METER)
in case if structure of second table is different and potentially has more columns that you don't need in output - use classic approach
select METER, if(t1.Metermodel = 'Other', t2.Metermodel, t1.Metermodel) as Metermodel
from MainTable t1
left join LeftTable t2
using(METER)
if applied to sample data in y our question - both have same output
The only time you will have null value is if there is no matching record in the second table. If you want to handle this, you can use the value from the main table as a fallback, which can be done using COALESCE.
CASE WHEN (EX.Metermodel) = 'Other'
THEN COALESCE(OJ.Metermodel, EX.Metermodel)
ELSE EX.Metermodel
END AS MeterModelRemoved

sql counting the number is not working correctly

I make related queries and the counting does not work correctly, when I connect 4 and join and add a condition, it does not count correctly, but without the 4th joina and the condition it works correctly. first option result = 2
SELECT
pxixolog_details.*,
directions.direction,
COUNT(directions.direction) procent
FROM
pxixolog_details
LEFT JOIN psixologs_direction ON pxixolog_details.id = psixologs_direction.psixolog_id
LEFT JOIN directions ON directions.id = psixologs_direction.direction_id
LEFT JOIN psixologs_weeks ON pxixolog_details.id = psixologs_weeks.psixolog_id
WHERE
directions.direction IN(
'Трудности в отношениях',
'Проблемы со сном',
'Нежелательная агрессия'
)
AND birthday BETWEEN '1956-04-29' AND '2021-04-29' AND psixologs_weeks.week = '4'
GROUP BY
pxixolog_details.id
and the second one doesn't work correctly. result = 4
SELECT
pxixolog_details.*,
directions.direction,
COUNT(directions.direction) procent
FROM
pxixolog_details
LEFT JOIN psixologs_direction ON pxixolog_details.id = psixologs_direction.psixolog_id
LEFT JOIN directions ON directions.id = psixologs_direction.direction_id
LEFT JOIN psixologs_weeks ON pxixolog_details.id = psixologs_weeks.psixolog_id
LEFT JOIN psixologs_times ON pxixolog_details.id = psixologs_times.psixolog_id
WHERE
directions.direction IN(
'Трудности в отношениях',
'Проблемы со сном',
'Нежелательная агрессия'
)
AND birthday BETWEEN '1956-04-29' AND '2021-04-29' AND psixologs_weeks.week = '4'
AND (psixologs_times.time = '09:00' OR psixologs_times.time = '10:00')
GROUP BY
pxixolog_details.id
what am I doing wrong?
You get double the amount of results when doing 4 JOINs because through the new (4th) JOIN you allow 2 records (9:00 and 10:00 o'clock) for each of the other joined records in the first 3 JOINs. That can lead to the observed result.
Check your data and make sure that your 4th JOIN condition yields a 1:1 record matching with the other data.
The last table has psixologs_times matches multiple rows for each psixolog_id.
You can easily see this using a query:
select psixolog_id, count(*)
from psixologs_times
group by psixolog_id
having count(*) > 1;
How you fix this problem depends on what you want to do. The simplest solution is to use count(distinct):
COUNT(DISTINCT directions.direction) as procent
However, this might just be hiding the problem. You might want to choose one row from the psixologs_times table. Or pre-aggregate it. Or do something else.

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.

Return blank data if the column is empty in SQL

I have run the following query which returns 36 rows of data
SELECT
A.OBJECTIVE, SUM(A.T_VALUE)
FROM
DB2ADM2.TFINTR10 A
WHERE
(A."YEAR" =10)
AND (A.OBJECTIVE BETWEEN 'WAAAA' AND 'WZZZZ')
GROUP BY
A.OBJECTIVE
When I merge with another table and add the Narration field (OB_Narr5) the rows of data are reduced as the Ob_Narr5 does not exist for every Objective, see sql.
SELECT A.OBJECTIVE, SUM ( A.T_VALUE ), B.OB_NARR5
FROM DB2ADM2.TFINTR10 A INNER JOIN DB2ADM2.TFINOBJP B ON B.OB_12345 = A.
OBJECTIVE
WHERE (A."YEAR" =10)
AND A.OBJECTIVE BETWEEN 'WAAAA' AND 'WZZZZ'
GROUP BY A.OBJECTIVE, B.OB_NARR5
The rows returned are now only 4.
How can I return all the rows including the blank fields and / or return just the rows with the blank fields?
Thanks for replies, Left and Full Outer Join both work.
How do I replace the <NULL> with a blank instead please?
WAAAA -173597.12 <NULL>
WABAA 222717.76 GENERAL
Use LEFT JOIN instead of INNER JOIN which doesnt drop entries of the left table containing empty columns
You can use Full Outer Join for preserving values from both the tables
or Left Outer Join for any particular table
select A.OBJECTIVE
,SUM(A.T_VALUE)
,B.OB_NARR5
from DB2ADM2.TFINTR10 A
left join DB2ADM2.TFINOBJP B on B.OB_12345 = A.OBJECTIVE
where A."YEAR" = 10
and A.OBJECTIVE between 'WAAAA' and 'WZZZZ'
group by A.OBJECTIVE
,B.OB_NARR5

SQL: SELECT DISTINCT not returning distinct values

The code below is supposed to return unique records in the lp_num field from the subquery to then be used in the outer query, but I am still getting multiples of the lp_num field. A ReferenceNumber can have multiple ApptDate records, but each lp_num can only have 1 rf_num. That's why I tried to retrieve unique lp_num records all the way down in the subquery, but it doesn't work. I am using Report Builder 3.0.
Current Output
Screenshot
The desired output would be to have only unique records in the lp_num field. This is because each value in the lp_num field is a pallet, one single pallet. the info to the right is when it arrived (ApptDate) and what the reference number is for the delivery (ref_num). Therefore, it makes no sense for a pallet to have multiple receipt dates...it can only arrive once...
SELECT DISTINCT
dbo.ISW_LPTrans.item,
dbo.ISW_LPTrans.lot,
dbo.ISW_LPTrans.trans_type,
dbo.ISW_LPTrans.lp_num,
dbo.ISW_LPTrans.ref_num,
(MIN(CONVERT(VARCHAR(10),dbo.CW_CheckInOut.ApptDate,101))) as appt_date_only,
dbo.CW_CheckInOut.ApptTime,
dbo.item.description,
dbo.item.u_m,
dbo.ISW_LPTrans.qty,
(CASE
WHEN dbo.ISW_LPTrans.trans_type = 'F'
THEN 'Produced internally'
ELSE
(CASE
WHEN dbo.ISW_LPTrans.trans_type = 'R'
THEN 'Received from outside'
END)
END
) as original_source
FROM
dbo.ISW_LPTrans
INNER JOIN dbo.CW_Dock_Schedule ON LTRIM(RTRIM(dbo.ISW_LPTrans.ref_num)) = dbo.CW_Dock_Schedule.ReferenceNumber
INNER JOIN dbo.CW_CheckInOut ON dbo.CW_CheckInOut.TruckID = dbo.CW_Dock_Schedule.TruckID
INNER JOIN dbo.item ON dbo.item.item = dbo.ISW_LPTrans.item
WHERE
(dbo.ISW_LPTrans.trans_type = 'R') AND
--CONVERT(VARCHAR(10),dbo.CW_CheckInOut.ApptDate,101) <= CONVERT(VARCHAR(10),dbo.ISW_LPTrans.trans_date,101) AND
dbo.ISW_LPTrans.lp_num IN
(SELECT DISTINCT
dbo.ISW_LPTrans.lp_num
FROM
dbo.ISW_LPTrans
INNER JOIN dbo.item ON dbo.ISW_LPTrans.item = dbo.item.item
INNER JOIN dbo.job ON dbo.ISW_LPTrans.ref_num = dbo.job.job AND dbo.ISW_LPTrans.ref_line_suf = dbo.job.suffix
WHERE
(dbo.ISW_LPTrans.trans_type = 'W' OR dbo.ISW_LPTrans.trans_type = 'I') AND
dbo.ISW_LPTrans.ref_num IN
(SELECT
dbo.ISW_LPTrans.ref_num
FROM
dbo.ISW_LPTrans
--INNER JOIN dbo.ISW_LPTrans on dbo.ISW_LPTrans.
WHERE
dbo.ISW_LPTrans.item LIKE #item AND
dbo.ISW_LPTrans.lot LIKE #lot AND
dbo.ISW_LPTrans.trans_type = 'F'
GROUP BY
dbo.ISW_LPTrans.ref_num
) AND
dbo.ISW_LPTrans.ref_line_suf IN
(SELECT
dbo.ISW_LPTrans.ref_line_suf
FROM
dbo.ISW_LPTrans
--INNER JOIN dbo.ISW_LPTrans on dbo.ISW_LPTrans.
WHERE
dbo.ISW_LPTrans.item LIKE #item AND
dbo.ISW_LPTrans.lot LIKE #lot AND
dbo.ISW_LPTrans.trans_type = 'F'
GROUP BY
dbo.ISW_LPTrans.ref_line_suf
)
GROUP BY
dbo.ISW_LPTrans.lp_num
HAVING
SUM(dbo.ISW_LPTrans.qty) < 0
)
GROUP BY
dbo.ISW_LPTrans.item,
dbo.ISW_LPTrans.lot,
dbo.ISW_LPTrans.trans_type,
dbo.ISW_LPTrans.lp_num,
dbo.ISW_LPTrans.ref_num,
dbo.CW_CheckInOut.ApptDate,
dbo.CW_CheckInOut.ApptTime,
dbo.item.description,
dbo.item.u_m,
dbo.ISW_LPTrans.qty
ORDER BY
dbo.ISW_LPTrans.lp_num
In a nutshell - the way you use DISTINCT is logically wrong from SQL perspective.
Your DISTINCT is in an IN subquery in the WHERE clause - and at that point of code it has absolutely no effect (except from the performance penalty). Think on it - if the outer query returns non-unique values of dbo.ISW_LPTrans.lp_num (which obvioulsy happens) those values can still be within the distinct values of the IN subquery - the IN does not enforce a 1-to-1 match, it only enforces the fact that the outer query values are within the inner values, but they can match multiple times. So it is definitely not DISTINCT's fault.
I would go through the following check steps:
See if there is insufficient JOIN ON condition(s) in the outer FROM section that leads to data multiplication (e.g. if a table has primary-to-foreign key relation on several columns, but you join on one of them only etc.).
Check which of the sources contains non-distinct records in the outer FROM section - then either cleanse your source, or adjust the JOIN condition and / or the WHERE clause so that you only pick distinct & correct records. In fact you might need to SELECT DISTINCT in the FROM sections - there it would make much more sense.