Showing posts with label expert. Show all posts
Showing posts with label expert. Show all posts

Friday, March 30, 2012

Query/View Question

I am trying to create a view that returns data from three tables and can't seem to get it to return the data that I want. I am no SQL expert, so hopefully someone can give me some insight into what I need to do.

The tables are basically set up like this:

TABLE 1

PrimaryKey

Textfield1

Textfield2

Textfield3

TABLE 2

PrimaryKey

Table1ForeignKey

Table3ForeignKey

Textfield1

TABLE 3

PrimaryKey

Textfield1

Textfield2

Textfield3

Table 1 and Table 3 are each joined to Table 2 on their respective Primary/Foreign Key fields.

I want the view to return all of the records from Table 1, even if there are no matching records in Table 2.

From Table 2 I only want the latest record for each record in Table 1.

I want the view to look something like this:

Table 1

PrimaryKey

Table1

Textfield1

Table2

Textfield

Table3

Textfield

In other words, I want to return one record in the view for each record in table 1, and I want the data from table 2 in each of those records to represent the last record added to table 2.

Can anyone enlighten me on the query necessary to get this view?

Hi,

some more questions:

how do you define "the latest" in table2 ?

HTH, Jens Suessmeyer,

http://www.sqlserver2005.de

|||Since the Primary Key field autoincrements, the 'latest' record from Table 2 will always be the max(table2.primarykey).|||

Perhaps my question will make more sense explained like this:

I will use an analogy of checking out books from the library.

Table 1 is a table of books, with a primary key of bookid.

Table 2 is a detail record of who withdrew the book, when, when it was returned, etc. with a primary key of DetailID and has a foreign key to Table 1 to identify the book as well as a foreign key to table 3 to identify who withdrew it.

Table 3 is a table of library card holders contact info with a primary key of CardholderID.

All of the primary keys are auto-incrementing.

I want the view to basically give me a snapshot of ALL books, and if it a particular book is currently withdrawn, I want to see who has it and when they checked it out.

I hope that makes more sense.

|||

OK, keeping your analogy in mind, the query should be like:

Select
T1.PrimaryKey,T1.TextField,
T2.PrimaryKey,T2.TextField,
T3.TextField
FROM Table1 T1
LEFT JOIN
(
SELECT Table1FK, Table3FK,Textfield
FROM Table2
INNER JOIN
(
SELECT MAX(PrimaryKey) as PK, Table1PK
FROM TABLE2
GROUP BY Table1PK
) SubQuery
ON Subquery.PK = Table2.PK
AND SubQuery.Table1PK = Table2.Table1PK
) T2
ON
T1.PrimaryKey = T2.Table1FK
INNER JOIN Table3 T3
ON T3.PrimaryKey = T2.Table1FK

untested....

HTH, Jens Suessmeyer.

http://www.sqlserver2005.de

Friday, March 23, 2012

Query using 'AND' on a linking table

Hi

I'm not an SQL expert and I'm having some problems doing a query on a linking table. I'm using SQL Server Compact Edition with the tables in question having the following (simplified) structure:

Contacts Table: ContactId (pk), DisplayName

SkillInstances Table: SkillInstID (pk), ObjectId(fk),SkillsId(fk)

Skills Table: SkillsId(pk), Skill

(The ObjectId in SkillInstances is ContactId in the Contacts table)

The idea is that a Contact can have one or more 'Skills'. Each Skill for a Contact has an SkillInstances row which references the particular Skill in the Skills table.

Typically I would want a query which returns Contacts with skills 'ABC' or 'XYZ'. This is no problem. But I cannot formulate a query that returns all Contacts with skills 'ABC' AND 'XYZ'.

SELECT Contacts.DisplayName
FROM SkillInstances INNER JOIN
Skills ON SkillInstances.SkillId = Skills.SkillId INNER JOIN
Contacts ON SkillInstances.ObjectId = Contacts.ContactId
WHERE (Skills.Skill = 'ABC') OR (Skills.Skill.= 'XYZ')

To get the AND condition, I tried creating two derived tables using the above SQL as a sub-queries but this does not seem to work on SQL Server CE.

Any ideas or thoughts much appreciated.

Regards

John Wilkie

Try the examples below which should both return the same results - one may be more performant than the other with your data.

Chris

Code Snippet

SELECT c.DisplayName

FROM Contacts c

WHERE EXISTS ( SELECT 1

FROM SkillInstances ski

INNER JOIN Skills sk ON sk.SkillID = ski.SkillID

WHERE ski.ObjectID = c.ContactID

AND sk.Skill = 'ABC' )

AND EXISTS ( SELECT 1

FROM SkillInstances ski

INNER JOIN Skills sk ON sk.SkillID = ski.SkillID

WHERE ski.ObjectID = c.ContactID

AND sk.Skill = 'XYZ' )

GO

SELECT c.DisplayName

FROM Contacts c

INNER JOIN SkillInstances ski ON ski.ObjectID = c.ContactID

INNER JOIN Skills sk ON sk.SkillID = ski.SkillID

WHERE sk.Skill IN('ABC', 'XYZ')

GROUP BY c.ContactID, c.DisplayName

HAVING COUNT(DISTINCT sk.Skill) = 2

GO

|||hi try this..

SELECT Contacts.DisplayName
FROM SkillInstances INNER JOIN
Skills ON SkillInstances.SkillId = Skills.SkillId INNER JOIN
Contacts ON SkillInstances.ObjectId = Contacts.ContactId
WHERE (Skills.Skill = 'ABC')
OR (Skills.Skill.= 'XYZ')
GROUP BY
Constacts.DisplayName
HAVING COUNT(Skills.Skill) = 2|||

here few more...

Code Snippet

Create Table #contacts(

[ContactId] int ,

[DisplayName] Varchar(100)

);

Insert Into #contactsValues('1','Nancy');

Insert Into #contactsValues('2','Andrew');

Insert Into #contactsValues('3','Janet');

Insert Into #contactsValues('4','Margaret');

Insert Into #contactsValues('5','Steven');

Create Table #skills (

[SkillsId] int ,

[Skill] Varchar(100)

);

Insert Into #skills Values('1','ASP.NET');

Insert Into #skills Values('2','SQL Server');

Insert Into #skills Values('3','C#');

Insert Into #skills Values('4','JavaScript');

Create Table #skillinstances (

[SkillInstID] int ,

[ObjectId] int ,

[SkillsId] int

);

Insert Into #skillinstances Values(1,1,1);

Insert Into #skillinstances Values(2,1,2);

Insert Into #skillinstances Values(3,1,3);

Insert Into #skillinstances Values(4,2,1);

Insert Into #skillinstances Values(5,2,2);

Insert Into #skillinstances Values(6,3,1);

Insert Into #skillinstances Values(7,3,3);

Insert Into #skillinstances Values(8,4,1);

Insert Into #skillinstances Values(9,4,2);

Insert Into #skillinstances Values(10,5,1);

Insert Into #skillinstances Values(11,5,3);

Insert Into #skillinstances Values(12,5,4);

--Using IN

SELECT

C.DisplayName

FROM

#SkillInstances SI

JOIN #Skills S1 ON SI.SkillsId = S1.SkillsIdAnd S1.Skill in ('ASP.NET')

INNER JOIN #Contacts C ON SI.ObjectId = C.ContactId

Where SI.ObjectId In

(

SELECT

SI.ObjectId

FROM

#SkillInstances SI

JOIN #Skills S1 ON SI.SkillsId = S1.SkillsIdAnd S1.Skill in ('C#')

)

--Using Exists

SELECT

C.DisplayName

FROM

#SkillInstances SIMain

JOIN #Skills S1 ON SIMain.SkillsId = S1.SkillsIdAnd S1.Skill in ('ASP.NET')

INNER JOIN #Contacts C ON SIMain.ObjectId = C.ContactId

Where Exists

(

SELECT

SI.ObjectId

FROM

#SkillInstances SI

JOIN #Skills S1 ON SI.SkillsId = S1.SkillsIdAnd S1.Skill in ('C#')

Where

SIMain.ObjectId = SI.ObjectId

)

--Simple & Faster One using Group By

SELECT

C.DisplayName

FROM

#SkillInstances SIMain

JOIN #Skills S1 ON SIMain.SkillsId = S1.SkillsIdAnd S1.Skill in ('ASP.NET','C#')

INNER JOIN #Contacts C ON SIMain.ObjectId = C.ContactId

Group By

C.DisplayName

Having

Count(Distinct Skill) =2

|||

Just to add that you should probably group by Contacts.ContactID (as in my example above) as you will receive eronous results if you group by only Contacts.DisplayName and your data contains duplicate Contacts.DisplayName values.

Chris

|||

Hi

Thank you for your quick response. Your solution works just fine. Thanks for your help.

Regards

John Wilkie

|||

Thanks to everyone for their prompt responses. All solutions seem to work fine. Thank you all again.

John Wilkie

Tuesday, March 20, 2012

Query to Retrieve Latest Row from each group !!

Hi SQL Query Expert,
My table looks like this:
CONTRACT_PK PARENT_PK CONTRACTOR_NAME CREATED_DATE
1 <NULL> ABC Company 4/7/2005
11:10:10 a.m.
2 1 XYZ Company
4/8/2005 10:10:12 a.m.
3 1 AAA Company
4/8/2005 12:10:00 p.m.
4 <NULL> BBB Company 4/8/2005
1:00:00 p.m.
5 4 CCC Company
4/8/2005 2:00:00 p.m.
6 <NULL> DDD Company 4/8/2005
3:00:00 p.m.
Basically record 2 and 3 are childs of record 1. Record 5 is child of record
4. Record 6 is a parent.
Could you please give me an example on how to retrieve rows with CONTRACT_PK
equals to 3, 5 and 6 from the above table?
My goal is to retrieve the latest child row if the parent has children. If
the parent doesn't have child(s), then it retrieves parent row. Here 3 and
5
are all latest child of parent 1 and 4. Parent 6 doesn't have child, so, i
t
should get retrieved too.
The table could have 1000 rows and they all fall in the same pattern for the
records retrieval.
Thank you so much!!!
-adamTry This
Select IsNull(C.CONTRACT_PK, P.CONTRACT_PK) ContractPK,
IsNull(C.PARENT_PK, P.PARENT_PK) ParentPK,
IsNull(C.CONTRACTOR_NAME, P.CONTRACTOR_NAME) Contractor,
IsNull(C.CREATED_DATE, P.CREATED_DATE) CreatedDate
From Table P
Left Join Table C
On C.Parent_PK = P.Contract_PK
And C.Created_Date = (Select Max(Created_Date)
From Table
Where Parent_PK =
C.Parent_PK)
"adam" wrote:

> Hi SQL Query Expert,
> My table looks like this:
> CONTRACT_PK PARENT_PK CONTRACTOR_NAME CREATED_DATE
> 1 <NULL> ABC Company 4/7/200
5
> 11:10:10 a.m.
> 2 1 XYZ Company
> 4/8/2005 10:10:12 a.m.
> 3 1 AAA Company
> 4/8/2005 12:10:00 p.m.
> 4 <NULL> BBB Company 4/8/20
05
> 1:00:00 p.m.
> 5 4 CCC Company
> 4/8/2005 2:00:00 p.m.
> 6 <NULL> DDD Company 4/8/200
5
> 3:00:00 p.m.
> Basically record 2 and 3 are childs of record 1. Record 5 is child of reco
rd
> 4. Record 6 is a parent.
> Could you please give me an example on how to retrieve rows with CONTRACT_
PK
> equals to 3, 5 and 6 from the above table?
> My goal is to retrieve the latest child row if the parent has children. I
f
> the parent doesn't have child(s), then it retrieves parent row. Here 3 an
d 5
> are all latest child of parent 1 and 4. Parent 6 doesn't have child, so,
it
> should get retrieved too.
> The table could have 1000 rows and they all fall in the same pattern for t
he
> records retrieval.
> Thank you so much!!!
> -adam
>|||adam,
Do not post the same problem twice, it does not help. Check your first threa
d.
AMB
"adam" wrote:

> Hi SQL Query Expert,
> My table looks like this:
> CONTRACT_PK PARENT_PK CONTRACTOR_NAME CREATED_DATE
> 1 <NULL> ABC Company 4/7/200
5
> 11:10:10 a.m.
> 2 1 XYZ Company
> 4/8/2005 10:10:12 a.m.
> 3 1 AAA Company
> 4/8/2005 12:10:00 p.m.
> 4 <NULL> BBB Company 4/8/20
05
> 1:00:00 p.m.
> 5 4 CCC Company
> 4/8/2005 2:00:00 p.m.
> 6 <NULL> DDD Company 4/8/200
5
> 3:00:00 p.m.
> Basically record 2 and 3 are childs of record 1. Record 5 is child of reco
rd
> 4. Record 6 is a parent.
> Could you please give me an example on how to retrieve rows with CONTRACT_
PK
> equals to 3, 5 and 6 from the above table?
> My goal is to retrieve the latest child row if the parent has children. I
f
> the parent doesn't have child(s), then it retrieves parent row. Here 3 an
d 5
> are all latest child of parent 1 and 4. Parent 6 doesn't have child, so,
it
> should get retrieved too.
> The table could have 1000 rows and they all fall in the same pattern for t
he
> records retrieval.
> Thank you so much!!!
> -adam
>