Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 General SQL Server Forums
 New to SQL Server Programming
 View with CASE statement

Author  Topic 

SBinVA
Starting Member

3 Posts

Posted - 2011-06-05 : 22:11:01
I've written a view that works, sort of. I'm hoping someone can show me how to perfect it. I've worked in Access for years but am still fairly new to SQL Server. I'm running SQL Server 2000 for the purposes of this post.

The view returns the correct information, but it duplicates each record. I'm assuming this has to do with the joins, but I can't seem to find it. Basically I have an Orders table that can house a One-Time Ship To address if the "UseOTS" flag is set to true, otherwise I join to the Ship To table and pull the information from there.

What am I doing wrong?

SB

CREATE VIEW dbo.uv_OpenOrderHeaders
AS

SELECT dbo.OrderHed.CustNum, dbo.OrderHed.OrderDate, dbo.OrderHed.OrderNum, dbo.OrderHed.PONum, dbo.OrderHed.NeedByDate,
dbo.OrderHed.RequestDate, dbo.SalesRep.Name, dbo.ShipVia.Description AS ShipVia, dbo.Terms.Description AS Terms, dbo.OrderHed.OpenOrder,
dbo.OrderHed.OrderComment, dbo.OrderHed.Character01 AS TopCap, dbo.OrderHed.Character02 AS WSFinish, dbo.OrderHed.Character03 AS WSTrim,
dbo.OrderHed.Character04 AS PanelFab, dbo.OrderHed.Character05 AS FlipFab, dbo.OrderHed.Character06 AS TackFab,
dbo.OrderHed.Character08 AS Job, dbo.OrderHed.Character10 AS CSR,
dbo.OrderHed.CheckBox01 AS CustAppr, dbo.OrderHed.ShortChar01 AS Class, dbo.OrderHed.ShortChar02 AS Paint,
dbo.OrderHed.ShortChar03 AS Base, dbo.OrderHed.ShortChar04 AS ShelfPaint, dbo.OrderHed.ShortChar05 AS ShelfStyle,
dbo.OrderHed.ShortChar06 AS Electric, dbo.OrderHed.ShortChar07 AS RailStyle, dbo.OrderHed.ChangeDate, dbo.OrderHed.ChangeTime,
CASE dbo.OrderHed.UseOTS WHEN 0 THEN dbo.ShipTo.Name ELSE dbo.OrderHed.OTSName END AS ShipName,
CASE dbo.OrderHed.UseOTS WHEN 0 THEN dbo.ShipTo.Address1 ELSE dbo.OrderHed.OTSAddress1 END AS ShipAdd1,
CASE dbo.OrderHed.UseOTS WHEN 0 THEN dbo.ShipTo.Address2 ELSE dbo.OrderHed.OTSAddress2 END AS ShipAdd2,
CASE dbo.OrderHed.UseOTS WHEN 0 THEN dbo.ShipTo.Address3 ELSE dbo.OrderHed.OTSAddress3 END AS ShipAdd3,
CASE dbo.OrderHed.UseOTS WHEN 0 THEN dbo.ShipTo.City ELSE dbo.OrderHed.OTSCity END AS ShipCity,
CASE dbo.OrderHed.UseOTS WHEN 0 THEN dbo.ShipTo.State ELSE dbo.OrderHed.OTSState END AS ShipState,
CASE dbo.OrderHed.UseOTS WHEN 0 THEN dbo.ShipTo.ZIP ELSE dbo.OrderHed.OTSZIP END AS ShipZip
FROM dbo.OrderHed LEFT OUTER JOIN dbo.ShipTo ON dbo.OrderHed.CustNum = dbo.ShipTo.CustNum AND dbo.OrderHed.ShipToNum = dbo.ShipTo.ShipToNum LEFT OUTER JOIN
dbo.Terms ON dbo.OrderHed.TermsCode = dbo.Terms.TermsCode LEFT OUTER JOIN dbo.SalesRep ON dbo.OrderHed.SalesRepList = dbo.SalesRep.SalesRepCode
LEFT OUTER JOIN dbo.ShipVia ON dbo.OrderHed.ShipViaCode = dbo.ShipVia.ShipViaCode
WHERE dbo.OrderHed.OpenOrder = 1

lionofdezert
Aged Yak Warrior

885 Posts

Posted - 2011-06-06 : 03:35:14
If the joins are must to apply as above mentioned then just use SELECT DISTINCT .... to get unique records

--------------------------
http://connectsql.blogspot.com/
Go to Top of Page

mmarovic
Aged Yak Warrior

518 Posts

Posted - 2011-06-06 : 04:01:43
No time to analyze now, just one question: Have you included useOTSFlag = <true> in (outer) join conditions?

Mirko

My blog: http://mirko-marovic-eng.blogspot.com/
Go to Top of Page

SBinVA
Starting Member

3 Posts

Posted - 2011-06-06 : 18:29:07
The SELECT DISTINCT worked but in my opinion it's more of a workaround and there's something not right with the query.

mmarovic - I'm not sure I follow you, how to I do that?
Go to Top of Page

jcelko
Esteemed SQL Purist

547 Posts

Posted - 2011-06-06 : 21:25:04
People cannot read your mind, so post your code AND clear specs if you really want help. Please post real DDL AND not narrative or your own personal programming language. Learn to use ISO-11179 rules for the data element names, avoid needless dialect AND use ISO-8601 temporal formats, codes AND so forth. Please tell us what SQL product AND release you are using. Tell us if you can change the DDL or if you are stuck with it.

For example, you never prefix VIEW with “vw-” oer “uv-” unless they deal with Volkswagen or ultraviolet. We do not use flags in SQL – that was assembly language in the 1950's.

Data element names do not change from table to table. THEY DO NOT DEPEND ON CONTEXT! That was stinking bad COBOL in the 1950's. Think about how silly and dangerous crap like “character01 AS top_cap” is and what it says about the (non-)design of this schema. Are you really disassembling strings in the DB?

Why do you have so many OUTER JOINs? The answer is that you made tables out of things that are actually attributes and not entities. For example, a sales representative code would be referenced in a column in an Order; you would not join to it. Look at all the things a “description” can be! Etc.

I think you need more help than you can get in a newsgroup. Do you want to try again?

--CELKO--
Books in Celko Series for Morgan-Kaufmann Publishing
Analytics and OLAP in SQL
Data and Databases: Concepts in Practice
Data, Measurements and Standards in SQL
SQL for Smarties
SQL Programming Style
SQL Puzzles and Answers
Thinking in Sets
Trees and Hierarchies in SQL
Go to Top of Page

mmarovic
Aged Yak Warrior

518 Posts

Posted - 2011-06-07 : 02:40:38
quote:
Originally posted by SBinVA

The SELECT DISTINCT worked but in my opinion it's more of a workaround and there's something not right with the query.

mmarovic - I'm not sure I follow you, how to I do that?

Actually, better idea is to use union and avoid outer joins.
select ...,
st.Name as shipName,
...
from dbo.orderHed oh
join dbo.shipto st on oh.custNum = st.custNo and oh.shipToNum = st.shipToNum
...
where oh.openOrder = 1 and
oh.useOTS = 0
union
select ...,
oh.OTSName as shipName,
...
from dbo.orderHed oh
left join dbo.terms t on ...
...
where oh.openOrder = 1 and
oh.useOTS = 1
Union would remove duplicates and improve query performance, but it would not solve the main problem: Why (in this case) at least one select from the union returns duplicate rows? I don't know cardinality of you relations so it is difficult to guess, maybe you have multiple terms per termsCode, I don't know.
To investigate that I would review cardinality per join conditions. If you still can't find the reason, you can make query with just data from order header, group by all columns and look at rows returned having count(*) > 1. If it does not help, repeat it by joining with one of tables involved etc until you figure it out. Also, I don't understand, why you have so many outer joins. Are some values of columns you use in join conditions optional (nullable)?

Mirko

My blog: http://mirko-marovic-eng.blogspot.com/
Go to Top of Page

SBinVA
Starting Member

3 Posts

Posted - 2011-06-08 : 00:27:16
jcelko - Thanks for your lack of input. I am fully aware that you nor anyone else can read minds. So, to help you, I'll briefly explain the prolific use of AS. The project involves reading data from a Progress DB (that I didn't design) in to SQL for use as the back end for a web project to present that data to customers. Giving the columns meaningful names helps the web developers and designers so they don't have to cross-reference 'Character01' to mean 'CSR' everywhere they need it. I like to call it customer service. Yes, the OUTER JOINs are needed to avoid data loss because some of the "key" fields are nullable. The "answer" you gave is incorrect, I didn't create the tables, I have to work with what I have to integrate with a DB someone else designed. So yes, I'm stuck with the DDL and I did state I was working in SQL Server 2000, perhaps Microsoft SQL Server 2000 would be more clear. In fact, if it matters, it is MS SQL Server 2000 that came bundled with Microsoft Small Business Server 2003 Premium.

Also, in my defense, I DID post this in the noobs forum.

Now, would you like to try again? I can assure you if your books are all written in the language of "prick", I will not be a customer.

mmarovic - Thanks for your useful suggestion, I hadn't thought of using UNION but will give it a try. All of the keys I use out of OrderHed are unique to the foreign key in the joining table. However, it is possible for the key to be null in OrderHed, hence the outer joins.

Logically the only place where this could return records at a precise 2:1 ratio is something to do with the CASE statement and/or the join to the ShipTo table. In looking at it, is it possible that the two-part key from OrderHed (CustNum and ShipToNum) to the ShipTo table is causing this? Is this syntax correct?

dbo.OrderHed LEFT OUTER JOIN dbo.ShipTo ON dbo.OrderHed.CustNum = dbo.ShipTo.CustNum AND dbo.OrderHed.ShipToNum = dbo.ShipTo.ShipToNum


Regardless, thanks for taking your time to look at it. I truly appreciate it.

SB
Go to Top of Page

mmarovic
Aged Yak Warrior

518 Posts

Posted - 2011-06-08 : 13:50:42
quote:
Originally posted by SBinVA
mmarovic - Thanks for your useful suggestion, I hadn't thought of using UNION but will give it a try. All of the keys I use out of OrderHed are unique to the foreign key in the joining table. However, it is possible for the key to be null in OrderHed, hence the outer joins.

Logically the only place where this could return records at a precise 2:1 ratio is something to do with the CASE statement and/or the join to the ShipTo table. In looking at it, is it possible that the two-part key from OrderHed (CustNum and ShipToNum) to the ShipTo table is causing this? Is this syntax correct?

dbo.OrderHed LEFT OUTER JOIN dbo.ShipTo ON dbo.OrderHed.CustNum = dbo.ShipTo.CustNum AND dbo.OrderHed.ShipToNum = dbo.ShipTo.ShipToNum


Regardless, thanks for taking your time to look at it. I truly appreciate it.

SB

You are wellcome. The syntax is correct, however you better change your habits and start using aliasis. It is more readable that way and also in some cases you have to do it when joining the same table multiple times.

You should not have duplicates if all fk columns make primary or unique key in reference tables. Somewhere it must not be true. Case expression in select column list do not cause any duplication. So, my advice stays, try investigation I suggested in previous post.

Mirko

My blog: http://mirko-marovic-eng.blogspot.com/
Go to Top of Page
   

- Advertisement -