SQL Question - What is wrong with my WHERE clause - sql

It's been a few years since I had to use SQL and I had to write a query – but I got results that I didn't expect. I've spent so many hours looking at it that I'm sure I'm missing something obvious but, when I run this below, my query is returning RateCode values other than what is in my WHERE statement.
What am I doing wrong? I feel like its a basic enough query (and I'm starting to panic that I've lost my skill)
SELECT
cs.Acct AS Site,
cs.Addr1 AS Address,
cs.City,
cs.State,
m.TypeDescr AS Service,
se.Quantity,
se.SvcCode,
se.SvcDescr,
sf.FreqDescr AS Frequency,
se.SvcId,
se.StartDate,
se.EndDate,
sr.ReasonDescr AS Reason,
svr.RateCode,
svr.StartDate AS RateStartDate,
svr.EndDate AS RateEndDate
FROM
wiSvcEquipment AS se
LEFT JOIN wiCustSite AS cs ON cs.SiteId = se.SiteId
LEFT JOIN wiMaterial AS m ON m.MatSubType = se.MatSubType
LEFT JOIN wiSvcReason AS sr ON sr.ReasonID = se.ReasonID
LEFT JOIN wiSvcVendRate AS svr ON svr.SvcId = se.SvcID
LEFT JOIN wiSvcCustRate as scr ON scr.RateCode = se.RateCode
LEFT JOIN wiSvcFreq AS sf ON sf.FreqID = se.FreqID
WHERE
se.CustId = ‘013714’
OR
se.CustId = ‘014831’
AND
svr.RateCode IN (
‘CHGCMBHAUL’, ‘CHGHAUFLAT’, ‘CHGHAUL2’, ‘CHGHAUL3’,
‘CHGHAULCOM’, ‘CHGHAULFE’, ‘CHGHAULING’, ‘CHGHAULMIN’,
‘CHGVCMBHAU’, ‘CHGVHAUFLT’, ‘CHGVHAULFE’, ‘CHGVHAULNG’,
‘CHGWKDHAUL’, ‘CLIHAUFLAT’, ‘CLIHAULFE’, ‘CLIHAULING’
) ;

Change your WHERE to use IN for both columns:
WHERE
se.CustId IN ( '013714', '014831' )
AND
svr.RateCode IN (
'CHGCMBHAUL', 'CHGHAUFLAT', 'CHGHAUL2', 'CHGHAUL3',
'CHGHAULCOM', 'CHGHAULFE', 'CHGHAULING', 'CHGHAULMIN',
'CHGVCMBHAU', 'CHGVHAUFLT', 'CHGVHAULFE', 'CHGVHAULNG',
'CHGWKDHAUL', 'CLIHAUFLAT', 'CLIHAULFE', 'CLIHAULING'
);
Or use an explicit logical group:
WHERE
(
se.CustId = '013714'
OR
se.CustId = '014831'
)
AND
svr.RateCode IN (
'CHGCMBHAUL', 'CHGHAUFLAT', 'CHGHAUL2', 'CHGHAUL3',
'CHGHAULCOM', 'CHGHAULFE', 'CHGHAULING', 'CHGHAULMIN',
'CHGVCMBHAU', 'CHGVHAUFLT', 'CHGVHAULFE', 'CHGVHAULNG',
'CHGWKDHAUL', 'CLIHAUFLAT', 'CLIHAULFE', 'CLIHAULING'
);
The two clauses above are strictly identical: in SQL the x IN ( a, b, c ) operator is just syntactic sugar for a series of ( x = a OR x = b OR x = c ) comparison.

did you mean
(se.CustId = ‘013714’ OR se.CustId = ‘014831’)
AND has precedence over OR

I can see three things:
You need parentheses -- or better yet -- IN for the first condition.
conditions on all but the first table in a series of LEFT JOINs should be in the ON clause.
Your strings have smart quotes, but they should be "straight" single quotes.
So:
SELECT . . .
FROM wiSvcEquipment se
wiCustSite cs
ON cs.SiteId = se.SiteId LEFT JOIN
wiMaterial m
ON m.MatSubType = se.MatSubType LEFT JOIN
wiSvcReason sr
ON sr.ReasonID = se.ReasonID AND
svr.RateCode IN ('CHGCMBHAUL', 'CHGHAUFLAT', 'CHGHAUL2', 'CHGHAUL3',
'CHGHAULCOM', 'CHGHAULFE', 'CHGHAULING', 'CHGHAULMIN’,
'CHGVCMBHAU', 'CHGVHAUFLT', 'CHGVHAULFE', 'CHGVHAULNG',
'CHGWKDHAUL', 'CLIHAUFLA’, 'CLIHAULFE', 'CLIHAULING'
) LEFT JOIN
LEFT JOIN
wiSvcVendRate svr
ON svr.SvcId = se.SvcID LEFT JOIN
wiSvcCustRate scr
ON scr.RateCode = se.RateCode LEFT JOIN
wiSvcFreq sf
ON sf.FreqID = se.FreqID
WHERE se.CustId IN ('013714', '014831')

if se.CustId = ‘013714’ clause is satisfied then no matter what the retcode is this query will return the rows.
Is your intention to use below condition:
WHERE
(se.CustId = ‘013714’
OR
se.CustId = ‘014831’)
AND
svr.RateCode IN (
‘CHGCMBHAUL’, ‘CHGHAUFLAT’, ‘CHGHAUL2’, ‘CHGHAUL3’,
‘CHGHAULCOM’, ‘CHGHAULFE’, ‘CHGHAULING’, ‘CHGHAULMIN’,
‘CHGVCMBHAU’, ‘CHGVHAUFLT’, ‘CHGVHAULFE’, ‘CHGVHAULNG’,
‘CHGWKDHAUL’, ‘CLIHAUFLAT’, ‘CLIHAULFE’, ‘CLIHAULING’
) ;

Related

SQL Subquery containing Joins

I'm using Hive hql. I am trying to inner join two tables filtering on issue_type='Impediments'
Now I have a new requirement to join dm_jira__label to include the label and issue_id columns. I have tried having a subquery adding the issue_id and label by using a left join with dm_jira__label on issue_id
INNER JOIN datamart_core.dm_jira__release
ON dm_jira.issue_id = dm_jira__release.issue_id;
(
SELECT b.issue_id, b.label AS jira_label
FROM datamart_core.dm_jira__label as B, datamart_core.dm_jira__release AS K
LEFT JOIN b
ON b.issue_id=k.issue_id
);
WHERE dm_jira.issue_type = 'Impediment') AS J
I am getting the following error:
AnalysisException: Illegal table reference to non-collection type: 'b' Path resolved to type: STRUCT<issue_id:DOUBLE,label:STRING>
See the full code below. thanks in advance.
SELECT DISTINCT
j.project_key AS jira_project_key,
j.issue_type,
j.issue_assignee AS impediment_owner,
j.issue_status AS impediment_status,
j.issue_priority AS impediment_priority,
j.issue_summary AS impediment_summary,
j.`release` AS jira_release,
j.sow AS sow_num,
j.issue_due_date_utc AS jira_issue_due_date_utc,
j.issue_id AS jira_issue_id,
s.sow_family
from (
--Subquery to combine dm_jira and dm_jira__release
SELECT dm_jira.project_key,
dm_jira.issue_type,
dm_jira.issue_assignee,
dm_jira.issue_status,
dm_jira.issue_priority,
dm_jira.issue_summary,
dm_jira.issue_due_date_utc,
dm_jira.issue_id,
dm_jira__release.`release`,
dm_jira__release.sow
from datamart_core.dm_jira
INNER JOIN datamart_core.dm_jira__release
ON dm_jira.issue_id = dm_jira__release.issue_id;
(
SELECT b.issue_id, b.label AS jira_label
FROM datamart_core.dm_jira__label as B, datamart_core.dm_jira__release AS K
LEFT JOIN b
ON b.issue_id=k.issue_id
);
WHERE dm_jira.issue_type = 'Impediment') AS J
INNER JOIN datamart_core.dm_asoe_jira_scrum_summary AS S
ON j.`release` = s.jira_release
AND j.sow = s.sow_num
AND j.project_key = s.jira_project_key;
; ends a whole statement, don't use it at the end of sub-queries or joins.
Using meaningless aliases such as B or K or J harms readability, don't do it.
FROM x, y is the same as FROM x CROSS JOIN y, it's not a list of tables you're going to join. This means that you have the following code...
(
SELECT
b.issue_id, b.label AS jira_label
FROM
datamart_core.dm_jira__label as B
CROSS JOIN
datamart_core.dm_jira__release AS K
LEFT JOIN
b
ON b.issue_id=k.issue_id
)
The b in the LEFT JOIN isn't a table, and causes your syntax error.
Then, your sub query just sits in the middle of the code, it's not joined on or used in any way. I think you intended a pattern more like this...
FROM
datamart_core.dm_jira
INNER JOIN
datamart_core.dm_jira__release
ON dm_jira.issue_id = dm_jira__release.issue_id;
LEFT JOIN
(
<your sub-query>
)
AS fubar
ON fubar.something = something.else
WHERE
dm_jira.issue_type = 'Impediment'
Even then, you don't actually need nested sub-queries at all. You can just keep adding joins, such as this...
SELECT
jira.project_key AS jira_project_key,
jira.issue_type,
jira.issue_assignee AS impediment_owner,
jira.issue_status AS impediment_status,
jira.issue_priority AS impediment_priority,
jira.issue_summary AS impediment_summary,
jrel.`release` AS jira_release,
jrel.sow AS sow_num,
jira.issue_due_date_utc AS jira_issue_due_date_utc,
jira.issue_id AS jira_issue_id,
jlab.label,
summ.sow_family
FROM
datamart_core.dm_jira AS jira
INNER JOIN
datamart_core.dm_jira__release AS jrel
ON jrel.issue_id = jira.issue_id
LEFT JOIN
datamart_core.dm_jira__label AS jlab
ON jlab.issue_id = jrel.issue_id
INNER JOIN
datamart_core.dm_asoe_jira_scrum_summary AS summ
ON summ.jira_release = jrel.`release`
AND summ.sow_num = jrel.sow
AND summ.jira_project_key = jira.project_key
WHERE
jira.issue_type = 'Impediment'
;

How can I transform this Code with Joins instead of using +(=) or =

I was trying Hours to transform this code(I think It is Oracle) with joins in SQL Server instead of
using +(=)/= but somehow i dont get the same result as using += or =. Can please someone help me out ?
SELECT KNVV.MANDT, KNVV.KUNNR,
KNVV.VTWEG, KNVV.BZIRK, KNVP.KUNN2
FROM KNA1, KNVV, KNVP, CDHDR
WHERE
AND `(KNVV.MANDT = KNA1.MANDT`
AND `KNVV.KUNNR = KNA1.KUNNR)`
AND `(KNVP.MANDT (+) = KNVV.MANDT`
AND `KNVP.KUNNR (+) = KNVV.KUNNR`
AND `KNVP.VTWEG (+) = KNVV.VTWEG)`
AND `(CDHDR.MANDANT (+) = KNVV.MANDT`
AND `CDHDR.OBJECTID (+) = KNVV.KUNNR)`
AND `(KNVV.VTWEG = KNVP.VTWEG)`
AND `KNVP.PARVW (+) = 'RG'`
AND CDHDR.OBJECTCLAS (+) = 'DEBI'
Without sample data its hard to test but it appears you want:
SELECT KNVV.MANDT, KNVV.KUNNR,
KNVV.VTWEG, KNVV.BZIRK, KNVP.KUNN2
FROM KNA1
INNER JOIN KNVV
ON ( KNVV.MANDT = KNA1.MANDT
AND KNVV.KUNNR = KNA1.KUNNR
)
INNER JOIN KNVP
ON ( KNVP.MANDT = KNVV.MANDT
AND KNVP.KUNNR = KNVV.KUNNR
AND KNVP.VTWEG = KNVV.VTWEG
AND KNVV.VTWEG = KNVP.VTWEG -- This duplicated condition makes it an
-- INNER JOIN and not a LEFT OUTER JOIN as
-- you are not using (+) in Oracle's legacy
-- syntax.
AND KNVP.PARVW = 'RG'
)
LEFT OUTER JOIN CDHDR
ON ( CDHDR.MANDANT = KNVV.MANDT
AND CDHDR.OBJECTID = KNVV.KUNNR
AND CDHDR.OBJECTCLAS = 'DEBI'
)
What you probably want is to make the second join a LEFT OUTER JOIN instead of an INNER JOIN but that is not what your current query is doing as you are using (KNVV.VTWEG = KNVP.VTWEG) rather than (KNVV.VTWEG = (+) KNVP.VTWEG) in your Oracle query.
You query can be converted to:
select
KNVV.MANDT,
KNVV.KUNNR,
KNVV.VTWEG,
KNVV.BZIRK,
KNVP.KUNN2
from KNA1
join KNVV on KNVV.MANDT = KNA1.MANDT
and KNVV.KUNNR = KNA1.KUNNR
left join KNVP on KNVP.MANDT = KNVV.MANDT -- left join defeated!
and KNVP.KUNNR = KNVV.KUNNR
and KNVP.VTWEG = KNVV.VTWEG
and KNVP.PARVW = 'RG'
left join CDHDR on CDHDR.MANDANT = KNVV.MANDT
and CDHDR.OBJECTID = KNVV.KUNNR
and CDHDR.OBJECTCLAS = 'DEBI'
where KNVV.VTWEG = KNVP.VTWEG -- silently converts left join into inner join
NOTE: the original query is malformed
Even though the original query tried to perform a left join against the table KNVP this join is silently converted into an inner join by the engine. Are you sure this query is working as expected?
Did you try inner JOIN?
SELECT KNVV.MANDT, KNVV.KUNNR,
KNVV.VTWEG, KNVV.BZIRK, KNVP.KUNN2
FROM KNA1, KNVV, KNVP, CDHDR
INNER JOIN KNVV ON KNA1.MANDT=KNVV.MANDT;
Something in this sense its more convenient.
documentation bellow
https://www.w3schools.com/sql/sql_join.asp

SQL- basic but still finding it complicated

I am working on SQL query which should return the list of Managers and the staff who reports to them.
Unfortunately there is no separate table for Employee or Staff but a single 'resource' table called ahsresources.
The managers are identified with a relation called 'C0'.
Even after trying various Joins, I am unable to extract the list. The idea is that a manager will run the report to see his reportees, as well as those staff who report to his own reportees
Example -
Now, if lets say HDY is running the query, then its should return him the below result
Below is the query I have created, but for the matter of understanding the issue, you can use the above example.
select a.description as manager1,a.rel_value as MGID,a.resource_id as Reportee1_MGR2,r.name,a.date_to as date, r.date_to,a1.resource_id as MG3ID,r1.name as Rep3Name,
a2.resource_id as MG4ID,r2.name as Rep4Name
from ahsrelvalue a
LEFT OUTER JOIN ahsresources r
ON r.resource_id = a.resource_id and r.client = a.client and a.date_to='12/31/2099'
LEFT OUTER JOIN ahsrelvalue a1
ON a1.rel_Value = a.resource_id and a1.client = a.client and a1.date_to = '12/31/2099'
LEFT OUTER JOIN ahsrelvalue a2
ON a2.rel_Value = a1.resource_id and a2.client = a1.client and a2.date_to = '12/31/2099'
LEFT OUTER JOIN ahsresources r1
ON r1.resource_id = a1.resource_id and r1.client = a1.client and a1.date_to='12/31/2099'
LEFT OUTER JOIN ahsresources r2
ON r2.resource_id = a2.resource_id and r2.client = a2.client and a2.date_to='12/31/2099'
where a.rel_Value = '$?resid' and a.rel_attr_id='C0' and r.date_to = '12/31/2099' and r1.date_to ='12/31/2099'
and r.status !='C' and r1.status!='C' and r2.status!='C'
In SQL Server, you can use a recursive query to traverse this hierarchical dataset:
with cte as (
select t.* from mytable where managerID = 6
union all
select t.*
from cte c
inner join mytable t on t.managerID = c.staffID
)
select * from cte

LEFT JOIN on multiple tables ERROR! (Table or view does not exist)

I have the following SQL Syntax:
SELECT firmenstamm.firmen_id,
firmenstamm.firmenname_1,
kreditorenstamm.kreditorenname_1,
debitor.debitoren_id,
debitor.deb_id_vom_kreditor,
debitorenstamm.debitorenname_1,
zahlung.zahlung_nr,
zahlung.zahlung_betrag,
zahlung.zahlung_betrag_offen,
zahlung.zahlung_datum,
kreditorenstamm.kreditoren_id,
bankbewegung.name_ag,
bankbewegung.verwendungzweck
FROM debitor,
debitorenstamm,
firmenstamm,
kreditorenstamm,
zahlung
LEFT JOIN z_bankbewegung ON zahlung.zahlungs_id = z_bankbewegung.zahlungs_id,
LEFT JOIN bankbewegung ON z_bankbewegung.babe_id = bankbewegung.babe_id
WHERE ( firmenstamm.firmen_id = kreditorenstamm.firmen_id ) and
( kreditorenstamm.kreditoren_id = debitor.kreditoren_id ) and
( debitor.debitoren_id = debitorenstamm.debitoren_id ) and
( debitor.kreditoren_id = zahlung.kreditoren_id ) and
( debitor.deb_id_vom_kreditor = zahlung.deb_id_vom_kreditor ) and
( ( zahlung.zahlung_betrag_offen > 0 ) )
My Problem now is the following:
As you can see I made a multiple left join on the same table. I always get the error message "Table or view does not exist" (ORA-00942).
zahlung
LEFT JOIN z_bankbewegung ON zahlung.zahlungs_id = z_bankbewegung.zahlungs_id,
LEFT JOIN bankbewegung ON z_bankbewegung.babe_id = bankbewegung.babe_id
I can't see my mistake. Does anyone have any idea?
You are mixing the old, ancient and fragile implicit joins (listing all tables separated by a comma in the FROM clause, then put the join conditions in to the WHERE clause) and the "modern"1) explicit JOIN operator. Don't do that. Use explicit JOINs for everything:
SELECT ...
FROM debitor
JOIN debitorenstamm ON debitor.debitoren_id = debitorenstamm.debitoren_id
JOIN kreditorenstamm ON kreditorenstamm.kreditoren_id = debitor.kreditoren_id
JOIN firmenstamm ON firmenstamm.firmen_id = kreditorenstamm.firmen_id
JOIN zahlung
ON debitor.kreditoren_id = zahlung.kreditoren_id
AND debitor.deb_id_vom_kreditor = zahlung.deb_id_vom_kreditor
LEFT JOIN z_bankbewegung ON zahlung.zahlungs_id = z_bankbewegung.zahlungs_id
LEFT JOIN bankbewegung ON z_bankbewegung.babe_id = bankbewegung.babe_id
WHERE zahlung.zahlung_betrag_offen > 0
1) "modern" is relative: explicit JOINs have been introduced in the SQL standard in 1992 more than 25 years ago. So that's hardly "modern" in the sense of "brand new".

JOIN syntax and order for multiple tables

SQL Gurus,
I have a query that uses the "old" style of join syntax as follows using 7 tables (table and column names changed to protect the innocent), as shown below:
SELECT v1_col, p1_col
FROM p1_tbl, p_tbl, p2_tbl, p3_tbl, v1_tbl, v2_tbl, v3_tbl
WHERE p1_code = 1
AND v1_code = 1
AND p1_date >= v1_date
AND p_uid = p1_uid
AND p2_uid = p1_uid AND p2_id = v2_id
AND p3_uid = p1_uid AND p3_id = v3_id
AND v2_uid = v1_uid
AND v3_uid = v1_uid
The query works just fine and produces the results it is supposed to, but as an academic exercise, I tried to rewrite the query using the more standard JOIN syntax, for example, below is one version I tried:
SELECT V1.v1_col, P1.p1_col
FROM p1_tbl P1, v1_tbl V1
JOIN p_tbl P ON ( P.p_uid = P1.p1_uid )
JOIN p2_tbl P2 ON ( P2.p2_uid = P1.p1_uid AND P2.p2_id = V2.v2_id )
JOIN p3_tbl P3 ON ( P3.p3_uid = P1.p1_uid AND P3.p3_id = V3.v3_id )
JOIN v2_tbl V2 ON ( V2.v2_uid = V1.v1_uid )
JOIN v3_tbl V3 ON ( V3.v3_uid = V1.v1_uid )
WHERE P1.p1_code = 1
AND V1.v1_code = 1
AND P1.p1_date >= V1.v1_date
But, no matter how I arrange the JOINs (using MS SQL 2008 R2), I keep running into the error:
The Multi-part identifier "col-name" could not be bound,
where "col-name" varies depending on the order of the JOINs I am attempting...
Does anyone have any good examples on how use the JOIN syntax with this number of tables??
Thanks in advance!
When you use JOIN-syntax you can only access columns from tables in your current join or previous joins. In fact it's easier to write the old syntax, but it's more error-prone, e.g. you can easily forget a join-condition.
This should be what you want.
SELECT v1_col, p1_col
FROM p1_tbl
JOIN v1_tbl ON p1_date >= v1_date
JOIN v2_tbl ON v2_uid = v1_uid
JOIN v3_tbl ON v3_uid = v1_uid
JOIN p_tbl ON p_uid = p1_uid
JOIN p2_tbl ON p2_uid = p1_uid AND p2_id = v2_id
JOIN p3_tbl ON p3_uid = p1_uid AND p3_id = v3_id
WHERE p1_code = 1
AND v1_code = 1
You are not naming the tables in your join such that it doesn't know which column is from which table. Try something like:
SELECT a.v1_col, b.p1_col
FROM p1_tbl b
JOIN p_tbl a ON b.p_uid = a.p1_uid
WHERE b.p1_code = 1
From your query above, I am assuming a naming convention of p2_uid comes from p2_tbl. Below id my best interpretation of WHERE joins to using INNER joins.
SELECT
v1_col, p1_col
FROM
p1_tbl
INNER JOIN p1_tbl
ON p1_tbl.p1_date >= v1_tbl.v1_date
INNER JOIN p_tbl
ON p_tbl.p_uid = p1_tbl.p1_uid
INNER JOIN p2_tbl
ON p2_tbl.p2_uid = p1_tbl.p1_uid
INNER JOIN v2_tbl
ON p2_tbl.p2_id = v2_tbl.v2_id
INNER JOIN p3_tbl
ON p3_tbl.p3_uid = p1_tbl.p1_uid
INNER JOIN v3_tbl
ON p3_tbl.p3_id = v3_tbl.v3_id
INNER JOIN v1_tbl
ON v1_tbl.v1_uid = v2_tbl.v2_uid
AND v1_tbl.v1_uid = v3_tbl.v2_uid
WHERE
p1_code = 1
AND
v1_code = 1
Some general points I have found useful in SQL statements with many joins.
Always fully qualify the names. I.e dont use ID , rahter use
TableName.ID
Dont use aliases unless there is meaning. (I.e. joining a table to
its self where aliasing is needed.)