Showing posts with label key. Show all posts
Showing posts with label key. Show all posts

Wednesday, March 21, 2012

need some help with my sql query

I'm still learning this stuff and I'm a bit confused. I have 3 tables: products, categories and subcategories. the products table has the foreign key for subcategories and the subcategories table has the foreign key for categories. I want to return a table that has the ProductID, SubCategoryID and CategoryID. I can't seem to fiqure out how to get the categoryID to the results table. I'm not sure if I'm supposed to use joins or subqueries to get the categoryID. All I have so far is this:


sql="SELECT Products.ProductID, Products.SubCategoryID FROM Products"

any help would be appreciated.I've come up with the following, i'm not sure if this is the correct way to do it, but it seems to work. I ran it through SQL Query Analyzer and it appears to give the results that i was expecting.


sql="SELECT Products.ProductID, Products.SubCategoryID, (SELECT CategoryID FROM SubCategories WHERE SubCategoryID = Products.SubCategoryID) as CategoryID
FROM Products";

If there is another/better/correct way to do this please let me know. Thanks.|||Another way to do it, which might be more efficient, is:


sql="SELECT Products.ProductID, Products.SubCategoryID, SubCategories.CategoryID FROM Products LEFT OUTER JOIN SubCategories ON Products.SubCategoryID = SubCategories.SubCategoryID";

Terri|||Very good, thanks. That is exactly what I was looking for.

Need some help with a Trigger

I created an instead of insert trigger which checks to see if the "key" of
the inserted record already exists. If it does, it copies the existing
record to another table, deletes it and inserts the new one. The problem I
get is when the insert statement coming into the trigger looks like the one
below I don't get my idx returned.
insert into resdata(resdata, data, alf) values (@.p1, @.p2, @.p3) select
scope_identity() as idx
here's the trigger:
ALTER TRIGGER [dbo].[tg_audit] ON [dbo].[resdata] WITH EXECUTE AS CALLER
INSTEAD OF INSERT AS
declare @.count int, @.comp int
declare @.resft int, @.data float, @.alf datetime
select @.resft = inserted.resft, @.data = data, @.alf = inserted.alf from
inserted;
select @.comp = idx from research where idx in (select research from resft
where idx = @.resft)
select @.count = count(data)from resdata where resft = @.resft and data =
@.data
if (@.count > 0) /* This record already exists so we don't want it added*/
return; // Don't know what to put here
else
begin
/* Create the same record in the history table */
insert into resdatah (resft, alf, data, ohm) select resft, alf, data,
getdate() from resdata where resft = @.resft
/* Delete the existing record from the this (resdata) table */
delete from resdata where resft = @.resft
/* Insert the new record */
insert into resdata (resft, data, alf) select resft, data, alf from
inserted
end"Joe" <J_no_spam@._no_spam_Fishinbrain.com> wrote in message
news:%23NWrFOcGFHA.3648@.TK2MSFTNGP09.phx.gbl...
> ALTER TRIGGER [dbo].[tg_audit] ON [dbo].[resdata] WITH EXECUTE AS CALLER
Please move this into the SQL Server 2005 newsgroups...
http://www.aspfaq.com/sql2005/show.asp?id=1
Adam Machanic
SQL Server MVP
http://www.sqljunkies.com/weblog/amachanic
--|||I'm actually using 2000 and 2005 (for testing). The trigger needs to work in
2000.
"Adam Machanic" <amachanic@.hotmail._removetoemail_.com> wrote in message
news:#mcqNYcGFHA.1528@.TK2MSFTNGP09.phx.gbl...
> "Joe" <J_no_spam@._no_spam_Fishinbrain.com> wrote in message
> news:%23NWrFOcGFHA.3648@.TK2MSFTNGP09.phx.gbl...
> Please move this into the SQL Server 2005 newsgroups...
> http://www.aspfaq.com/sql2005/show.asp?id=1
>
> --
> Adam Machanic
> SQL Server MVP
> http://www.sqljunkies.com/weblog/amachanic
> --
>
>|||"Joe" <J_no_spam@._no_spam_Fishinbrain.com> wrote in message
news:u2r3zbcGFHA.2748@.tk2msftngp13.phx.gbl...
> I'm actually using 2000 and 2005 (for testing). The trigger needs to work
in
> 2000.
The EXECUTE AS syntax is new for 2005 so you're going to have some
problems there...
Anyway, two suggestions: One, this might be a case where @.@.IDENTITY
should be used rather than SCOPE_IDENTITY() -- since the insert is being
done in the scope of the trigger, not in the scope of the initial INSERT
statement, @.@.IDENTITY should return the correct value. Second, you could
SELECT SCOPE_IDENTITY() within the trigger after you do the insert.
Adam Machanic
SQL Server MVP
http://www.sqljunkies.com/weblog/amachanic
--|||Your trigger will fail if more than one row is inserted. Never write
triggers like that.
When you have an INSTEAD OF trigger the @.@.IDENTITY returns the last
inserted IDENTITY value but SCOPE_IDENTITY() won't. Neither are very
useful within a trigger itself because a trigger should always be able
to handle multiple row inserts.
EXECUTE AS CALLER isn't supported in SQL2000.
Please post DDL and sample data INSERTs if you need more help.
David Portas
SQL Server MVP
--|||ok so how do I set the value of idx for the inserted return?
idx = @.idx // if record already existed
and
idx = select_scope_identity() if the trigger inserted the row?
"Adam Machanic" <amachanic@.hotmail._removetoemail_.com> wrote in message
news:#7Qr6ecGFHA.552@.TK2MSFTNGP12.phx.gbl...
> "Joe" <J_no_spam@._no_spam_Fishinbrain.com> wrote in message
> news:u2r3zbcGFHA.2748@.tk2msftngp13.phx.gbl...
work
> in
> The EXECUTE AS syntax is new for 2005 so you're going to have some
> problems there...
> Anyway, two suggestions: One, this might be a case where @.@.IDENTITY
> should be used rather than SCOPE_IDENTITY() -- since the insert is being
> done in the scope of the trigger, not in the scope of the initial INSERT
> statement, @.@.IDENTITY should return the correct value. Second, you could
> SELECT SCOPE_IDENTITY() within the trigger after you do the insert.
>
> --
> Adam Machanic
> SQL Server MVP
> http://www.sqljunkies.com/weblog/amachanic
> --
>|||This table is a read-only table except for a single user. The inserts are
done like this:
insert into resdata(resdata, data, alf) values (@.p1, @.p2, @.p3) select
scope_identity() as idx
The goal is to check and see if there is a row with resdata =
inserted.resdata. If so, the existing record needs to be copied to another
table and the new one inserted.
"David Portas" <REMOVE_BEFORE_REPLYING_dportas@.acm.org> wrote in message
news:1109177795.995989.220250@.f14g2000cwb.googlegroups.com...
> Your trigger will fail if more than one row is inserted. Never write
> triggers like that.
> When you have an INSTEAD OF trigger the @.@.IDENTITY returns the last
> inserted IDENTITY value but SCOPE_IDENTITY() won't. Neither are very
> useful within a trigger itself because a trigger should always be able
> to handle multiple row inserts.
> EXECUTE AS CALLER isn't supported in SQL2000.
> Please post DDL and sample data INSERTs if you need more help.
> --
> David Portas
> SQL Server MVP
> --
>|||I'm not sure why @.@.IDENTITY doesn't meet your requirements as Adam
suggested but anyway IDENTITY should never be the only key of a table
therefore you can use an alternate key to retrieve the inserted
IDENTITY:
INSERT INTO x (key_col, ...) VALUES (@.key_col, ...)
SET @.id =
(SELECT id_col
FROM x
WHERE key_col = @.key_col)
David Portas
SQL Server MVP
--|||I'm . Given this insert statement (which is being generated from a
SqlDataAdapter):
insert into resdata(resdata, data, alf) values (@.p1, @.p2, @.p3) select
scope_identity() as idx
how do I reference column idx to set the value in both cases? 1 - when I
want to set it to an existing idx; 2- when I want to set it to the new idx?
In case 2 I can use the @.@.IDENTITY to get the identity of the column but how
do I assign it so it's returned back. Maybe I'm with the way the
SqlDataAdapter gets the values back.
"David Portas" <REMOVE_BEFORE_REPLYING_dportas@.acm.org> wrote in message
news:1109179471.440296.167900@.f14g2000cwb.googlegroups.com...
> I'm not sure why @.@.IDENTITY doesn't meet your requirements as Adam
> suggested but anyway IDENTITY should never be the only key of a table
> therefore you can use an alternate key to retrieve the inserted
> IDENTITY:
> INSERT INTO x (key_col, ...) VALUES (@.key_col, ...)
> SET @.id =
> (SELECT id_col
> FROM x
> WHERE key_col = @.key_col)
> --
> David Portas
> SQL Server MVP
> --
>|||"Joe" <J_no_spam@._no_spam_Fishinbrain.com> wrote in message
news:u9rGUwcGFHA.332@.TK2MSFTNGP10.phx.gbl...
> This table is a read-only table except for a single user. The inserts are
> done like this:
> insert into resdata(resdata, data, alf) values (@.p1, @.p2, @.p3) select
> scope_identity() as idx
I could be wrong, but it looks to me like that is two separate statements:
1) insert into resdata(resdata, data, alf) values(@.p1, @.p2, @.p3)
2) select scope_identity() as idx

> The goal is to check and see if there is a row with resdata =
> inserted.resdata. If so, the existing record needs to be copied to another
> table and the new one inserted.
I think what your trigger needs to do is something like:
--Backup Matched Rows
INSERT INTO backuptable
SELECT * FROM maintable INNER JOIN inserted ON
maintable.resdata=inserted.resdata
--Delete Matched Rows
DELETE From maintable
WHERE EXISTS(
SELECT * from mainTable INNER JOIN inserted
ON maintable.resdata = inserted.resdata)
--Add All Rows
INSERT Into maintable
SELECT * from Inserted
Good Luck,
Jim

Monday, March 12, 2012

Need random/unique "IDs" for key verification

I need to be able to create completely random and unique keys for a key verification system, which would require a user to enter a pre-defined key in order to activate their account, but I need to be able to create those keys on the fly.

This is going to be a key that will be mailed to them on paper, and unfortunately means it needs to be relatively short in order to prevent too much confusion while they are typing it in.

I like the newID() function in SQL, but the ID that it creates is a bit excessive to say the least for someone to have to type when registerring.

I use C#, so I wouldn't have much of a problem creating a small app to create x number of keys, which will sit in the DB until I need them, but I would rather not have to fill the DB with a million or so ID's which might never be used, and don't want to create too little that I have to track when I might need to add more, in case I start to run low on ID's.

Re-using ID's may be an option, but I would prefer to keep them intact for the life of the accounts.

If there is something that I can do to simulate the newID() function, but generate unique/random ID's which look more like this: A97-2C5-77D than this: A972C577-DFB0-064E-1189-0154C99310DAAC12 I would be very grateful to know about it.

Thanks!

You could use Membership.GeneratePassword Method

It allows control of length and complexity both of the generated password

http://msdn2.microsoft.com/en-us/library/system.web.security.membership.generatepassword.aspx

need query...its urgent

hi friends,

I am facing one problem...
I am using ms-access .
I have parent table with fields (empid(primary key),password,flag).and child table with fields (empid(fk),empname,date,intime,outime,remarks).

If i enter empid and name of month,the output contains fields like:empid,empname,date,intime,outime,remarks.

My problem is if i enter empid and name of month,it has to get all records of employee(holding that empid) throughout the specified month..

Please send solution for this...its very urgent.......Hi..
Send me your query for getting records
by
ramesh

Wednesday, March 7, 2012

Need I........

If I've indexed field "A","B","C" with primary key, So do I still need to
index field "B"?That depends on how you access the table. If your WHERE clause looks this
this:
WHERE B = x
and you do this often you would probably benefit from another index on B
alone. If you do this:
WHERE A = y AND B = x
There is no need. The only time an index will use the columns in a compound
index that are not the first ones in the index expression is if it scans the
entire index. This is usually not the desired effect.
Andrew J. Kelly SQL MVP
"Bpk. Adi Wira Kusuma" <adi_wira_kusuma@.yahoo.com.sg> wrote in message
news:OAQMYfHvFHA.3896@.TK2MSFTNGP15.phx.gbl...
> If I've indexed field "A","B","C" with primary key, So do I still need to
> index field "B"?
>

Monday, February 20, 2012

Need help writing a query

Database consists of the following 4 tables with respective
attributes:

CUSTOMER(C#, CUSTOMER NAME, ADDRESS), the key is [C#]
ITEM(I#, ITEM NAME, MANUFACTURER, YEAR), the key is [I#]
BOUGHT(C#, I#, DATE, QUANTITY), the key is [C#, I#,DATE]
PREFER(I#, C#), the key is [I#, C#]

I'm trying to construct the following query (in SQL)

List of customers that bought all the items that John prefers.

I can get the list of all the items that John prefers, but I'm not
sure how to check that list against customers who bought ALL those
items. I'm assuming it's either a division or some sort of subtraction
but I'm not sure how to formulate the SQL query.

Any and all help is appreciated, thanks!(tizmagik@.gmail.com) writes:

Quote:

Originally Posted by

Database consists of the following 4 tables with respective
attributes:
>
CUSTOMER(C#, CUSTOMER NAME, ADDRESS), the key is [C#]
ITEM(I#, ITEM NAME, MANUFACTURER, YEAR), the key is [I#]
BOUGHT(C#, I#, DATE, QUANTITY), the key is [C#, I#,DATE]
PREFER(I#, C#), the key is [I#, C#]
>
I'm trying to construct the following query (in SQL)
>
List of customers that bought all the items that John prefers.
>
I can get the list of all the items that John prefers, but I'm not
sure how to check that list against customers who bought ALL those
items. I'm assuming it's either a division or some sort of subtraction
but I'm not sure how to formulate the SQL query.


This smells of class assignment, but OK, let's go for it anyway.

If memory serves this is something they for some reason I've never
understood call relational division. In less occluded terms, a HAVING
clause can shortcut the need for a couple of EXISTS and NOT EXISTS.

SELKCT C.C#, C.CUSTOMER_NAME
FROM CUSTOMER C
JOIN (SELECT B.C#
FROM BOUGHT B
GROUP BY B.C#
HAVING COUNT(DISTINCT B.I#) =
(SELECT COUNT(*)
FROM PREFER P
JOIN CUSTOMER C ON P.C# = C.C#
WHERE C.CUSTOMER_NAME = 'John')) AS res
ON C.C# = res.C#

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se
Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pr...oads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodin...ions/books.mspx|||Erland Sommarskog wrote:

Quote:

Originally Posted by

(tizmagik@.gmail.com) writes:

Quote:

Originally Posted by

>Database consists of the following 4 tables with respective
>attributes:
>>
>CUSTOMER(C#, CUSTOMER NAME, ADDRESS), the key is [C#]
>ITEM(I#, ITEM NAME, MANUFACTURER, YEAR), the key is [I#]
>BOUGHT(C#, I#, DATE, QUANTITY), the key is [C#, I#,DATE]
>PREFER(I#, C#), the key is [I#, C#]
>>
>I'm trying to construct the following query (in SQL)
>>
>List of customers that bought all the items that John prefers.
>>
>I can get the list of all the items that John prefers, but I'm not
>sure how to check that list against customers who bought ALL those
>items. I'm assuming it's either a division or some sort of subtraction
>but I'm not sure how to formulate the SQL query.


>
This smells of class assignment, but OK, let's go for it anyway.
>
If memory serves this is something they for some reason I've never
understood call relational division. In less occluded terms, a HAVING
clause can shortcut the need for a couple of EXISTS and NOT EXISTS.
>
SELKCT C.C#, C.CUSTOMER_NAME
FROM CUSTOMER C
JOIN (SELECT B.C#
FROM BOUGHT B
GROUP BY B.C#
HAVING COUNT(DISTINCT B.I#) =
(SELECT COUNT(*)
FROM PREFER P
JOIN CUSTOMER C ON P.C# = C.C#
WHERE C.CUSTOMER_NAME = 'John')) AS res
ON C.C# = res.C#


That will select all customers who bought the same /number/ of
items as what John prefers, but not necessarily the same items.

I think this will select all customers who bought all the items
that John prefers:

SELECT C.C#, C.CUSTOMER_NAME
FROM CUSTOMER C
JOIN BOUGHT B ON C.C# = B.C#
JOIN PREFER P ON B.I# = P.I#
JOIN CUSTOMER J ON P.C# = J.C# AND J.CUSTOMER_NAME = 'John'
GROUP BY C.C#, C.CUSTOMER_NAME
HAVING COUNT(*) = (
SELECT COUNT(*)
FROM PREFER P
JOIN CUSTOMER J ON P.C# = J.C# AND J.CUSTOMER_NAME = 'John'
)|||Erland: Why would it matter if it's a class assignment or not? Is not
the purpose of a Usenet group to share and learn from each other? What
relevance is it what the knowledge will be used for? Thank you for
your attempt anyway, but Ed's answer seems more in line with what the
query is intended to do.

Thank you Ed, seems to be what I'm looking for, it's interesting, I
never even though of setting up a Count, but now that I look at it,
it's hard to imagine any other way of doing it.

Thanks again :)|||tizmagik@.gmail.com wrote:

Quote:

Originally Posted by

Thank you Ed, seems to be what I'm looking for, it's interesting, I
never even though of setting up a Count, but now that I look at it,
it's hard to imagine any other way of doing it.


I thought of doing J JOIN P LEFT JOIN B and looking for nulls, but I
can't figure out a way to do it, and even if there is one, it would
probably be less clear than the COUNT = COUNT method.|||<tizmagik@.gmail.comwrote in message
news:1176697766.757819.271590@.b75g2000hsg.googlegr oups.com...

Quote:

Originally Posted by

Erland: Why would it matter if it's a class assignment or not?


It matters if you're asking others to do your homework. Some professors
frown upon that. (and it could, in some cases, be considered a form of
cheating.)

Quote:

Originally Posted by

Is not
the purpose of a Usenet group to share and learn from each other?


Oh certainly. And I think Erland would agree, many of us here love to help
others (and certainly to learn from others). But from time to time (and I'm
not claiming you're one of them) who come here looking simply for answers to
homework problems, not necessarily understanding. That benefits no one in
the long run.

Quote:

Originally Posted by

What
relevance is it what the knowledge will be used for? Thank you for
your attempt anyway, but Ed's answer seems more in line with what the
query is intended to do.
>
Thank you Ed, seems to be what I'm looking for, it's interesting, I
never even though of setting up a Count, but now that I look at it,
it's hard to imagine any other way of doing it.
>
Thanks again :)
>


--
Greg Moore
SQL Server DBA Consulting Remote and Onsite available!
Email: sql (at) greenms.com http://www.greenms.com/sqlserver.html|||>Why would it matter if it's a class assignment or not? Is not the purpose of a Usenet group to share and learn from each other? <<

In most university systems having someone else do your homework gets
you kicked out of school. It is academic fraud. I know. I have had
two kids expelled from schools in New Zealand and Australia for doing
this. An old friend of mine got a "social engineer" taken out of
Georgia Tech; etc.|||--CELKO-- wrote:

Quote:

Originally Posted by

Quote:

Originally Posted by

Quote:

Originally Posted by

>>Why would it matter if it's a class assignment or not? Is not the purpose of a Usenet group to share and learn from each other? <<


>
In most university systems having someone else do your homework gets
you kicked out of school. It is academic fraud. I know. I have had
two kids expelled from schools in New Zealand and Australia for doing
this. An old friend of mine got a "social engineer" taken out of
Georgia Tech; etc.


Same rule applies here at the University of Washington.

Get caught cheating and it is a one-way trip.

Anyone that thinks instructors such as myself are not watching
these groups is in the wrong business.
--
Daniel A. Morgan
University of Washington
damorgan@.x.washington.edu
(replace x with u to respond)
Puget Sound Oracle Users Group
www.psoug.org|||(tizmagik@.gmail.com) writes:

Quote:

Originally Posted by

Erland: Why would it matter if it's a class assignment or not? Is not
the purpose of a Usenet group to share and learn from each other?


But Usenet is not the best place to learn everything. If you have some
experience in the field of SQL programming, I can assume that you can
understand the solution I post to some extend and learn from it.

But if you are a student who is not interested in doing his homework?

I remember way back when, when I was a student myself, and also worked as
an assistant teacher in programming. Back in those days, the assignments
were made on paper, and when the student was approved for this week's
exercise I would give him a paper with the "ideal" solution. Sometimes
it happened that students arrived to the classroom with this ideal
solution, in which case I told them not do to it again. And I did not
approve them for that assignment. (It was permitted to miss one or two.)

One year I had a group in Programming 2, an optional class which taught
programming structures. I had one guy who consistently arrived with
the ideal solution, and I knew that his girlfriend was taking the same
class. I figured that at this stage, he should know better than cheating,
so I did not say anything. I approved his "solutions" without a comment
and let him go. But these assignments were not all - there was a written
exam as well. And when the results came up, his girl-friend was there.
But, not surprisingly, he wasn't. He had just copied the ideal solutions,
but he hadn't learnt anything.

Quote:

Originally Posted by

Thank you Ed, seems to be what I'm looking for, it's interesting, I
never even though of setting up a Count, but now that I look at it,
it's hard to imagine any other way of doing it.


Sorry for the incorrect solution, but there is a standard recommendation
for this type of questions, and that is that you post:

o CREATE TABLE statements for your table(s).
o INSERT statements with sample data.
o The desireed output, given the sample.

That makes it easy to copy and paste to develop a tested solution. Without
that, most people here tend to just type something up, and sometimes
there are errors.

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se
Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pr...oads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodin...ions/books.mspx|||I am fairly new to SQL programming and believe me that wasn't the only
thing that the assignment asked, however this question was the one
question that I had a lot of trouble with and the lack of a book for
the class (it's strictly lecture notes) was what brought me to look
for help elsewhere.

If I would have based the SQL query on the examples given by the
professor I would have gotten a list of all customers who bought *at
least one* item that "john" prefers, as apposed to the correct list
(all customers who bought *all* the items that john prefers).
Furthermore, the professor did not go over COUNT so I really did not
see any way of doing it with what he has gone over so far. Perhaps
there is a solution without using COUNT, I will be sure to ask the
professor during next lecture.

Thanks for those that helped.|||On 16 Apr 2007 21:15:59 -0700, tizmagik@.gmail.com wrote:

Quote:

Originally Posted by

Perhaps
>there is a solution without using COUNT, I will be sure to ask the
>professor during next lecture.


Hi tizmagik,

Indeed, there is. It is called "inverse logic". If a customer has bought
every item John prefers, than clearly, there can not be any single item
that is preferred by John but that the customer didn't buy. I'm sure
that you're able to cough up the actual query for that logic. :-)

This solution is actually the solution most people produce first for
this problem. Maybe because many classes explain subqueries and NOT
EXISTS before moving on to aggregates and HAVING? Or maybe it's just
related to how our brain functions? Anyway, the version as posted by Ed
looks like (I didn't check in detail) the second standard solution to
this problem, based on the logic "if a customer buys everything John
prefers, then the number of items bought by the customers *and* prefered
by John must be equal to the number of items prefered by John. Outside
of class, you'd probably try both against the actual data on the actual
database to figure out which one gives the best performance.

--
Hugo Kornelis, SQL Server MVP
My SQL Server blog: http://sqlblog.com/blogs/hugo_kornelis|||(tizmagik@.gmail.com) writes:

Quote:

Originally Posted by

I am fairly new to SQL programming and believe me that wasn't the only
thing that the assignment asked, however this question was the one
question that I had a lot of trouble with and the lack of a book for
the class (it's strictly lecture notes) was what brought me to look
for help elsewhere.
>
If I would have based the SQL query on the examples given by the
professor I would have gotten a list of all customers who bought *at
least one* item that "john" prefers, as apposed to the correct list
(all customers who bought *all* the items that john prefers).
Furthermore, the professor did not go over COUNT so I really did not
see any way of doing it with what he has gone over so far. Perhaps
there is a solution without using COUNT, I will be sure to ask the
professor during next lecture.


So that's another problem with asking for help with class assignments
on Usenet. While the COUNT may be a more elegant solution, the professor
probably wanted you to exercise in the use of EXISTS and NOT EXISTS.
Which certainly is an investment worth making, because such problem
as commonplace. (While the exercise you had, has a disctinct flavoour
of class assignment. Did I ever encounter such a problem myself? I can't
recall any.)

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se
Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pr...oads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodin...ions/books.mspx|||Thanks for your input guys.

I'll be sure to post here when the solution without using COUNT is
covered (assuming there is one).|||Okay, this is what I have come up with so far:

SELECT c1.Customer_Name
FROM Customer c1
WHERE c1.CustomerID IN (
SELECT B.CustomerID
FROM Bought B
WHERE B.ItemID IN (
SELECT P.ItemID
FROM Prefer P, Customer c2
WHERE c2.Customer_Name = 'John'
AND c2.CustomerID = P.CustomerID ) )

But that brings me back to the problem where it will list customers
that bought *at least one* of the items that John prefers, not ALL of
the items that John prefers, that query gives:
John
Jeremy
Michelle

The expected answer is just 'Michelle' as being the only customer that
bought ALL of the items that John prefers with the following data:

-CUSTOMER table
CREATE TABLE Customer (
CustomerID int(4) NOT NULL,
Customer_Name varchar(30) NOT NULL,
Address varchar(30) NOT NULL,
PRIMARY KEY (CustomerID)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO Customer VALUES (1000, 'John', '123 John St.');
INSERT INTO Customer VALUES (1001, 'Jeremy', '456 Jeremy Ave.');
INSERT INTO Customer VALUES (1002, 'Michelle', '789 Michelle Blvd.');
INSERT INTO Customer VALUES (1003, 'Laura', '1011 Laura Way');
INSERT INTO Customer VALUES (1004, 'Nicholas', '1004 Nicholas Place');
INSERT INTO Customer VALUES (1005, 'James', '1005 James Drive');

-ITEM table
CREATE TABLE Item (
ItemID int(11) NOT NULL,
Item_Name varchar(30) NOT NULL,
Manufacturer varchar(30) NOT NULL,
`Year` int(4) NOT NULL,
PRIMARY KEY (ItemID)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO Item VALUES (9000, 'Camera', 'Nikkon', 1997);
INSERT INTO Item VALUES (9001, 'Camera', 'Sony', 1998);
INSERT INTO Item VALUES (9002, 'Camera', 'Olympus', 2001);
INSERT INTO Item VALUES (9003, 'Camera', 'Olympus', 2001);
INSERT INTO Item VALUES (9004, 'Camera', 'Polaroid', 1991);
INSERT INTO Item VALUES (9005, 'Laptop', 'Dell', 2006);
INSERT INTO Item VALUES (9006, 'Laptop', 'HP', 2005);
INSERT INTO Item VALUES (9007, 'Desktop', 'Dell', 2002);
INSERT INTO Item VALUES (9008, 'Desktop', 'Apple', 2004);
INSERT INTO Item VALUES (9009, 'PDA', 'Palm', 2003);
INSERT INTO Item VALUES (9010, 'PDA', 'Handspring', 1998);
INSERT INTO Item VALUES (9011, 'HDTV', 'Sony', 2004);
INSERT INTO Item VALUES (9012, 'HDTV', 'Samsung', 2005);
INSERT INTO Item VALUES (9013, 'HDTV', 'Toshiba', 2003);
INSERT INTO Item VALUES (9014, 'HDTV', 'Mitsubishi', 2003);

-BOUGHT table
CREATE TABLE Bought (
CustomerID int(4) NOT NULL,
ItemID int(4) NOT NULL,
`Date` date NOT NULL,
Quantity int(5) NOT NULL,
PRIMARY KEY (CustomerID,ItemID,`Date`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO Bought VALUES (1002, 9000, '2007-04-01', 5);
INSERT INTO Bought VALUES (1002, 9001, '2007-04-30', 2);
INSERT INTO Bought VALUES (1002, 9008, '2007-04-09', 1);
INSERT INTO Bought VALUES (1002, 9014, '2007-04-15', 1);
INSERT INTO Bought VALUES (1001, 9001, '2007-04-16', 1);
INSERT INTO Bought VALUES (1001, 9008, '2007-04-16', 1);
INSERT INTO Bought VALUES (1000, 9008, '2007-04-16', 5);
INSERT INTO Bought VALUES (1000, 9001, '2007-04-17', 2);
INSERT INTO Bought VALUES (1005, 9003, '2007-04-16', 2);
INSERT INTO Bought VALUES (1004, 9002, '2007-04-16', 1);
INSERT INTO Bought VALUES (1001, 9011, '2007-02-16', 3);
INSERT INTO Bought VALUES (1001, 9010, '2007-02-16', 3);
INSERT INTO Bought VALUES (1003, 9012, '2007-02-16', 1);
INSERT INTO Bought VALUES (1005, 9013, '2007-02-16', 2);
INSERT INTO Bought VALUES (1004, 9006, '2007-04-01', 1);

-PREFER table
CREATE TABLE Prefer (
ItemID int(4) NOT NULL,
CustomerID int(4) NOT NULL,
PRIMARY KEY (ItemID,CustomerID)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO Prefer VALUES (9000, 1000);
INSERT INTO Prefer VALUES (9001, 1000);
INSERT INTO Prefer VALUES (9002, 1004);
INSERT INTO Prefer VALUES (9003, 1003);
INSERT INTO Prefer VALUES (9006, 1001);
INSERT INTO Prefer VALUES (9007, 1004);
INSERT INTO Prefer VALUES (9007, 1005);
INSERT INTO Prefer VALUES (9008, 1000);
INSERT INTO Prefer VALUES (9008, 1002);
INSERT INTO Prefer VALUES (9008, 1004);
INSERT INTO Prefer VALUES (9009, 1002);
INSERT INTO Prefer VALUES (9013, 1005);
INSERT INTO Prefer VALUES (9014, 1000);

Again, any help is appreciated. (Yes, the professor didn't go over
AutoNumber fields yet in case you're wondering :) )|||A little closer... I believe this would be the right SQL
theoretically, but this will only work in an Oracle DB or DB that
supports the MINUS operation (MySQL doesnt), so I will try to
reformulate this without using MINUS. I'm guessing it's some sort of
JOIN operation where you check for Nulls and select those that are not
Null...

SELECT B1.CustomerID
FROM Bought B1
WHERE NOT EXISTS (
( SELECT Prefer.ItemID
FROM Prefer, Customer
WHERE Customer.Customer_Name = 'John'
AND Prefer.CustomerID = Customer.CustomerID
) MINUS (
SELECT B2.ItemID
FROM Bought B2
WHERE B2.CustomerID = B1.CustomerID )
)

Any help would be appreciated.|||tizmagik@.gmail.com wrote:

Quote:

Originally Posted by

Okay, this is what I have come up with so far:
>
SELECT c1.Customer_Name
FROM Customer c1
WHERE c1.CustomerID IN (
SELECT B.CustomerID
FROM Bought B
WHERE B.ItemID IN (
SELECT P.ItemID
FROM Prefer P, Customer c2
WHERE c2.Customer_Name = 'John'
AND c2.CustomerID = P.CustomerID ) )
>
But that brings me back to the problem where it will list customers
that bought *at least one* of the items that John prefers, not ALL of
the items that John prefers, that query gives:


I think this will work:

SELECT c1.Customer_Name
FROM Customer c1
WHERE 0 = (
SELECT COUNT(*)
FROM Customer C2
JOIN Prefer P ON C2.CustomerID = P.CustomerID
LEFT JOIN Bought B ON P.ItemID = B.ItemID
AND B.CustomerID = C1.CustomerID
WHERE C2.Customer_Name = 'John'
AND B.CustomerID IS NULL
)

but I still think the positive approach (COUNT = COUNT) is a lot
easier to understand.|||On Apr 17, 9:43 pm, Ed Murphy <emurph...@.socal.rr.comwrote:

Quote:

Originally Posted by

tizma...@.gmail.com wrote:

Quote:

Originally Posted by

Okay, this is what I have come up with so far:


>

Quote:

Originally Posted by

SELECT c1.Customer_Name
FROM Customer c1
WHERE c1.CustomerID IN (
SELECT B.CustomerID
FROM Bought B
WHERE B.ItemID IN (
SELECT P.ItemID
FROM Prefer P, Customer c2
WHERE c2.Customer_Name = 'John'
AND c2.CustomerID = P.CustomerID ) )


>

Quote:

Originally Posted by

But that brings me back to the problem where it will list customers
that bought *at least one* of the items that John prefers, not ALL of
the items that John prefers, that query gives:


>
I think this will work:
>
SELECT c1.Customer_Name
FROM Customer c1
WHERE 0 = (
SELECT COUNT(*)
FROM Customer C2
JOIN Prefer P ON C2.CustomerID = P.CustomerID
LEFT JOIN Bought B ON P.ItemID = B.ItemID
AND B.CustomerID = C1.CustomerID
WHERE C2.Customer_Name = 'John'
AND B.CustomerID IS NULL
)
>
but I still think the positive approach (COUNT = COUNT) is a lot
easier to understand.


Thanks Ed, but I'm trying to avoid using COUNT since that was not
covered in class.|||tizmagik@.gmail.com wrote:

Quote:

Originally Posted by

On Apr 17, 9:43 pm, Ed Murphy <emurph...@.socal.rr.comwrote:

Quote:

Originally Posted by

>tizma...@.gmail.com wrote:

Quote:

Originally Posted by

>>Okay, this is what I have come up with so far:
>>SELECT c1.Customer_Name
>>FROM Customer c1
>>WHERE c1.CustomerID IN (
>> SELECT B.CustomerID
>> FROM Bought B
>> WHERE B.ItemID IN (
>> SELECT P.ItemID
>> FROM Prefer P, Customer c2
>> WHERE c2.Customer_Name = 'John'
>> AND c2.CustomerID = P.CustomerID ) )
>>But that brings me back to the problem where it will list customers
>>that bought *at least one* of the items that John prefers, not ALL of
>>the items that John prefers, that query gives:


>I think this will work:
>>
>SELECT c1.Customer_Name
>FROM Customer c1
>WHERE 0 = (
> SELECT COUNT(*)
> FROM Customer C2
> JOIN Prefer P ON C2.CustomerID = P.CustomerID
> LEFT JOIN Bought B ON P.ItemID = B.ItemID
> AND B.CustomerID = C1.CustomerID
> WHERE C2.Customer_Name = 'John'
> AND B.CustomerID IS NULL
>)
>>
>but I still think the positive approach (COUNT = COUNT) is a lot
>easier to understand.


>
Thanks Ed, but I'm trying to avoid using COUNT since that was not
covered in class.


SELECT C1.Customer_Name
FROM Customer C1
WHERE NOT EXISTS (
SELECT P.ItemID
FROM Customer C2
JOIN Prefer P ON C2.CustomerID = P.CustomerID
LEFT JOIN Bought B ON P.ItemID = B.ItemID
AND B.CustomerID = C1.CustomerID
WHERE C2.Customer_Name = 'John'
AND B.CustomerID IS NULL
)

or

SELECT C1.Customer_Name
FROM Customer C1
WHERE NOT EXISTS (
SELECT P.ItemID
FROM Customer C2
JOIN Prefer P ON C2.CustomerID = P.CustomerID
WHERE C2.Customer_Name = 'John'
AND P.ItemID NOT IN (
SELECT B.ItemID
FROM Bought B
WHERE B.CustomerID = C1.CustomerID
)
)|||On Apr 17, 10:03 pm, Ed Murphy <emurph...@.socal.rr.comwrote:

Quote:

Originally Posted by

tizma...@.gmail.com wrote:

Quote:

Originally Posted by

On Apr 17, 9:43 pm, Ed Murphy <emurph...@.socal.rr.comwrote:

Quote:

Originally Posted by

tizma...@.gmail.com wrote:
>Okay, this is what I have come up with so far:
>SELECT c1.Customer_Name
>FROM Customer c1
>WHERE c1.CustomerID IN (
> SELECT B.CustomerID
> FROM Bought B
> WHERE B.ItemID IN (
> SELECT P.ItemID
> FROM Prefer P, Customer c2
> WHERE c2.Customer_Name = 'John'
> AND c2.CustomerID = P.CustomerID ) )
>But that brings me back to the problem where it will list customers
>that bought *at least one* of the items that John prefers, not ALL of
>the items that John prefers, that query gives:
I think this will work:


>

Quote:

Originally Posted by

Quote:

Originally Posted by

SELECT c1.Customer_Name
FROM Customer c1
WHERE 0 = (
SELECT COUNT(*)
FROM Customer C2
JOIN Prefer P ON C2.CustomerID = P.CustomerID
LEFT JOIN Bought B ON P.ItemID = B.ItemID
AND B.CustomerID = C1.CustomerID
WHERE C2.Customer_Name = 'John'
AND B.CustomerID IS NULL
)


>

Quote:

Originally Posted by

Quote:

Originally Posted by

but I still think the positive approach (COUNT = COUNT) is a lot
easier to understand.


>

Quote:

Originally Posted by

Thanks Ed, but I'm trying to avoid using COUNT since that was not
covered in class.


>
SELECT C1.Customer_Name
FROM Customer C1
WHERE NOT EXISTS (
SELECT P.ItemID
FROM Customer C2
JOIN Prefer P ON C2.CustomerID = P.CustomerID
LEFT JOIN Bought B ON P.ItemID = B.ItemID
AND B.CustomerID = C1.CustomerID
WHERE C2.Customer_Name = 'John'
AND B.CustomerID IS NULL
)
>
or
>
SELECT C1.Customer_Name
FROM Customer C1
WHERE NOT EXISTS (
SELECT P.ItemID
FROM Customer C2
JOIN Prefer P ON C2.CustomerID = P.CustomerID
WHERE C2.Customer_Name = 'John'
AND P.ItemID NOT IN (
SELECT B.ItemID
FROM Bought B
WHERE B.CustomerID = C1.CustomerID
)
)


That first one didn't work for me, some syntax error, not sure why,
might just be a phpMyAdmin problem, but that second one worked
beautifully.

I'm trying to step through it and understand it line by line now...
this is what I understand from it:

You are selecting all the customers that are not in the following:
- You are selecting all the Items that john prefers, from the list of
items that are not in the list of items that customers have bought

haha really confusing, but I think I get it. Thanks so much for your
help.|||tizmagik@.gmail.com wrote:

Quote:

Originally Posted by

That first one didn't work for me, some syntax error, not sure why,
might just be a phpMyAdmin problem,


You do realize this isn't a MySQL group?

Quote:

Originally Posted by

but that second one worked beautifully.
>
I'm trying to step through it and understand it line by line now...
this is what I understand from it:
>
You are selecting all the customers that are not in the following:
- You are selecting all the Items that john prefers, from the list of
items that are not in the list of items that customers have bought


For each customer, you're looking for items that John prefers
but the customer didn't buy; if there is no such item, then the
customer gets selected.|||I couldn't find a suitable MySQL (or just SQL group) that was as
active as this one. Thanks though.|||(tizmagik@.gmail.com) writes:

Quote:

Originally Posted by

I couldn't find a suitable MySQL (or just SQL group) that was as
active as this one. Thanks though.


There is a comp.databases.mysql. Don't how much traffic there is though.

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se
Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pr...oads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodin...ions/books.mspx