Click here to monitor SSC

Lionel Clarke

Software Engineer - Red Gate Software

Sql Puzzle 2

Published Friday, November 04, 2005 4:46 PM

/*
Todays puzzle comes from Andras who incudentally got the best
solution so far to the last puzzle.

We have two tables a letters table and a numbers table. The letters table
is a letter followed by three numbers. The idea is to write a query that
returns all the letters that have all numbers listed in the numbers table.
This is probably best explaind in an example. so the Letters table contains

a,1,2,3
a,4,5,6
a,4,5,6
b,1,2,3
c,1,2,3
c,4,5,3
d,1,9,4
d,2,8,5
d,3,7,6
d,4,6,7
e,1,2,3
e,4,5,6
e,4,5,6
e,4,6,7

The numbers table contains.
1,2,3
4,5,6
4,5,6

So for a letter to be selected it must have three entries in the letters table
One with 1,2,3. A second with 4,5,6. A third with 4,5,6. So if there is a
duplicate in the numbers table there must be a duplicate in the letters table.
In the example above the result will be a and e. A is returned as it has
exactally the three numbers following it that are in the numbers table. E is
also returned as it also has all of the entries in the numbers table and it
doesn't matter if there are extra ones.

The expected result from the data bellow should be:

Letter
------
a
e

Happy coding :)
*/
SET NOCOUNT ON

DECLARE @Letters TABLE
(
    Letter Char(1) NOT NULL,
    NumberA INT NOT NULL,
    NumberB INT NOT NULL,
    NumberC INT NOT NULL
)
DECLARE @Numbers TABLE
(
    NumberA INT NOT NULL,
    NumberB INT NOT NULL,
    NumberC INT NOT NULL
)

INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'a', 1, 2, 3
INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'a', 2, 3, 3
INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'a', 1, 2, 3
INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'a', 1, 3, 4

INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'b', 1, 2, 3
INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'b', 2, 3, 3

INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'c', 1, 2, 3
INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'c', 1, 2, 3
INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'c', 1, 2, 3
INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'c', 1, 2, 3
INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'c', 1, 2, 3

INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'd', 6, 5, 3
INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'd', 3, 2, 4
INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'd', 7, 2, 3
INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'd', 1, 4, 3
INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'd', 1, 2, 3

INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'e', 1, 2, 3
INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'e', 2, 3, 3
INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'e', 1, 2, 3

INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'f', 1, 2, 3
INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'f', 2, 3, 8
INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'f', 7, 3, 3
INSERT INTO @Letters(Letter, NumberA, NumberB, NumberC)
    SELECT 'f', 1, 2, 3



INSERT INTO @Numbers(NumberA, NumberB, NumberC)
    SELECT 1, 2, 3
INSERT INTO @Numbers(NumberA, NumberB, NumberC)
    SELECT 1, 2, 3
INSERT INTO @Numbers(NumberA, NumberB, NumberC)
    SELECT 2, 3, 3

SET NOCOUNT OFF
by James

Comments

 

AlexM said:

-- Hi. This is my solution to the puzzle. It seems to be stupid, but nevertheless it seems to be working :-)
SELECT L.Letter
FROM
(SELECT N.NumberA, N.NumberB, N.NumberC, N = COUNT(*)
FROM @Numbers N
GROUP BY N.NumberA, N.NumberB, N.NumberC) N
INNER JOIN (SELECT L.Letter, L.NumberA, L.NumberB, L.NumberC, N = COUNT(*)
FROM @Letters L
GROUP BY L.letter, L.NumberA, L.NumberB, L.NumberC) L ON N.NumberA = L.NumberA AND N.NumberB = L.NumberB AND N.NumberC = L.NumberC
AND  N.N = L.N
GROUP BY L.Letter
HAVING COUNT(*) = (SELECT COUNT(*) FROM (SELECT NumberA FROM @Numbers GROUP BY NumberA, NumberB, NumberC) T)
ORDER BY 1

-- The 2nd solution is shorter, but it can only be used in case we're really sure there are letters that satisfy task condition, otherwise the result is incorrect:
SELECT TOP 1 WITH TIES L.Letter
FROM
(SELECT L.Letter, L.NumberA, L.NumberB, L.NumberC, N = COUNT(*)
FROM @Letters L
GROUP BY L.letter, L.NumberA, L.NumberB, L.NumberC) L
INNER JOIN (SELECT N.NumberA, N.NumberB, N.NumberC, N = COUNT(*)
FROM @Numbers N
GROUP BY N.NumberA, N.NumberB, N.NumberC) N ON N.NumberA = L.NumberA AND N.NumberB = L.NumberB AND N.NumberC = L.NumberC
AND  N.N = L.N
GROUP BY L.Letter
ORDER BY COUNT(*) DESC
March 24, 2008 3:43 PM
 

ORKO said:

IN oracle i would solve the problem like this:
select A.letter
   from
   (select letter,numberA,numberB,numberC,count(*)cnt
   from letters
   group by letter,numberA,numberB,numberC
   )A,
   
   (  
   select NumberA, NumberB, NumberC,count(*) cnt
   from
   numbers
   group by NumberA, NumberB, NumberC
    )B
 where
    A.numberA=B.numberA
and     A. numberB= B. numberB
and     A.numberC= B.numberC
and     A.cnt >= B.cnt
group by a.letter
having count(*)=(select count(*) from (select distinct NumberA, NumberB, NumberC from numbers))
order by 1                



March 29, 2008 7:09 AM
 

SunilDutt N said:

How about this ???

SELECT DISTINCT Letter FROM @Letters L
INNER JOIN @Numbers N ON L.NumberA = N.NumberA AND L.NumberB = N.NumberB AND L.NumberC = N.NumberC
May 27, 2009 5:58 AM
 

SunilDutt N said:



SELECT DISTINCT Q.Letter FROM
(
SELECT Letter,L.NumberA,L.NumberB, L.NumberC
FROM @Letters L INNER JOIN @Numbers N ON N.NumberA = L.NumberA AND N.NumberB = L.NumberB AND N.NumberC = L.NumberC
GROUP BY Letter,L.NumberA,L.NumberB, L.NumberC
HAVING (COUNT(*) >= (SELECT COUNT(*) FROM @Numbers WHERE NumberA = L.NumberA AND NumberB = L.NumberB AND NumberC = L.NumberC))
) Q
GROUP BY Q.Letter
HAVING COUNT(Letter) = (SELECT COUNT(*) FROM @Numbers )
May 27, 2009 6:13 AM
 

Fun with SQL (games, painting, puzzles) « 1st blog, pre-beta version… said:

January 24, 2010 2:03 AM
 

sreekanth munagala said:

How about this query?

------------------------------------------------------------------------------------------------
CREATE TABLE xx_numbers(noa NUMBER, nob NUMBER, noc NUMBER);

INSERT INTO xx_numbers VALUES(1,2,3);

INSERT INTO xx_numbers VALUES(4,5,6);

INSERT INTO xx_numbers VALUES(4,5,6);

CREATE TABLE xx_letters(letter CHAR(1),noa NUMBER, nob NUMBER, noc NUMBER);

INSERT INTO xx_letters VALUES('a',1,2,3);

INSERT INTO xx_letters VALUES('a',4,5,6);

INSERT INTO xx_letters VALUES('a',4,5,6);

INSERT INTO xx_letters VALUES('b',1,2,3);

INSERT INTO xx_letters VALUES('b',4,5,6);

------------------------------------------------------------------------------------------------
SELECT letter
FROM
(
SELECT lwnc.letter, SUM(CASE WHEN lwnc.cnt <> nwc.cnt THEN 1 ELSE 0 END ) cnt_mismatch
FROM
(
SELECT *
FROM
(
SELECT l.letter,l.noa,l.nob,l.noc,COUNT(*) cnt
FROM
(
SELECT letter
FROM
(
SELECT DISTINCT letter
FROM xx_letters
)x
WHERE NOT EXISTS (SELECT 1 FROM xx_numbers
             WHERE (noa,nob,noc) NOT IN (SELECT noa,nob,noc FROM xx_letters WHERE letter = x.letter))
)lwan
,xx_letters l
WHERE lwan.letter = l.letter
GROUP BY l.letter,l.noa,l.nob,l.noc
)
)lwnc
,(SELECT noa,nob,noc,COUNT(*) cnt
 FROM xx_numbers
 GROUP BY noa,nob,noc
)nwc
WHERE lwnc.noa = nwc.noa
AND lwnc.nob = nwc.nob
AND lwnc.noc = nwc.noc
GROUP BY lwnc.letter
)
WHERE cnt_mismatch = 0
------------------------------------------------------------------------------------------------
Regards,
Sreekanth Munagala
October 25, 2010 6:58 AM
You need to sign in to comment on this blog
<November 2005>
SuMoTuWeThFrSa
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910
How to Kill a Company in One Step or Save it in Three
 The majority of companies that suffer a major data loss subsequently go out of business. David Wesley... Read more...

Migrating from OCS 2007 R2 to Lync: Part 4
 Having migrated the rest of our users and legacy resources across, and start getting ready to... Read more...

Automated Script-generation with Powershell and SMO
 In the first of a series of articles on automating the process of building, modifying and copying SQL... Read more...

Seth Godin: Big in the IT Business
 Seth Godin has transformed our understanding of marketing in IT. He invented the concept of 'permission... Read more...

Using SQL Test Database Unit Testing with TeamCity Continuous Integration
 With database applications, the process of test and integration can be frustratingly slow because so... Read more...