I have a table which is a simple lists of ID numbers and NAMES - I am trying to write a SQL which only returns rows where the NAME does not have particular IDs.
This has been stumping me - the query below returns all as they have other IDs from the exclude lists (large range of IDs). How to structure a query where only those who don't have ID 2 or 3 are returned -- i.e. only returns 'bob' for table below.
select * from TABLE where ID not in (2, 3)
ID NAMES
1 bob
1 alice
2 alice
1 dave
2 dave
3 dave
4 dave
Thank you.
One method is group by and having:
select name
from t
group by name
having sum(case when ID in (2, 3) then 1 else 0 end) = 0;
If you want the original ids, you can add listagg(id, ',') within group (order by id) to the select. Or use not exists:
select t.*
from t
where not exists (select 1
from t t2
where t2.name = t.name and
t2.id in (2, 3)
);
I have two temporary tables with single column
Table 1
MaXAge (Contains maximum age of each kind)
-----------
15
15
11
Table 2
KGroup (Contains each kind)
--------------------------------------------------
Cat
Dog
Parrot
AND another Table Pets with fields
PetID Name Kind Gender Age OwnerID
NOW, I want to display name of animals with maximum age group by kind
You can do this without using any temp tables
SELECT name, age
FROM pets p
JOIN (SELECT kind, MAX(age) max_age FROM pets GROUP BY kind) AS sub ON sub.kind = p.kind AND sub.max_age = p.age
I'm trying to join the result of two referencing tables to get row values which are referencing different table names, which rows are selectable by their uuid.
my tables look like this:
table entry
table map
table cats
table dogs
nrrefInt
id name mapRef breed
mapRef breed
1 123
123'dogs'
456 'bengal'
123 'sheepdog'
2 456
456 'cats'
888 'birma' 999 'poodle'
3 789
789'dogs'
4 123
refInt of entry is referencing to map. the name of map is the reference to tables in addition with the field id which is also applied on the tables cats/dogs (dynamic tables loading).
// subset 1: list of numbers that needs to be loaded from entry table (1-4)
SELECT DISTINCT refInt FROM entry WHERE nr in (1,2,3,4)
// subset 2: get all names from map that have the same id like refInt from subset1
SELECT name FROM map WHERE id in subset1
// main query: load all rows from table with the given name
// from map table that have the same mapRef value on it
SELECT * FROM (subset2.names) WHERE mapRef IN (subset2.ids)
result should be the rows:
1) 456 bengal
2) 123 sheepdog
I also made a SQLFiddle of it.
Is there a way to combine this to one query?
It's going to look something like:
SqlFiddle
select
sub.nr,
sub.breed
from (
select e.nr, e.refInt,
case
when c.breed is not null then c.breed
when d.breed is not null then d.breed
else null
end as breed
from (
select e.nr, e.refInt, m.name
from entry e
inner join map m on e.refInt = m.id
) e
left join cats c on e.refInt = c.mapRef and e.name = 'cats'
left join dogs d on e.refInt = d.mapref and e.name = 'dogs'
) sub
where sub.breed is not null
This is going to be very poor in performance.
Now the IMO the correct schema would be:
table entry
nr refint
1 123
2 456
3 789
4 124 (duplicate?)
table breed
mapRef breed species
123 sheepdog 1
999 poodle 1
456 bengal 2
888 birma 2
table species
id species
1 dogs
2 cats
This is normalized and has very good performance.
Note how the following query fully achieves the desired result set and fully demonstrates how the tables cats and dogs are truly just partitions of a single entity animals. The schema should be reworked to reflect this new understanding. This query is also efficient because the inclusion test id pushed to the depths of the innermost CTE's, at the level where actual table rows are being read, without relying on the engine to discover this potential optimization (which can be problematic with UNIONs).
with
cats2 as (
select species='cat', mapref, breed
from cats animals
join entry on entry.refint = animals.mapref
where entry.nr in (1,2,3,4)
),
dogs2 as (
select species='dog', mapref, breed
from dogs animals
join entry on entry.refint = animals.mapref
where entry.nr in (1,2,3,4)
),
animals as (
select species, mapref, breed from cats2
union all
select species, mapref, breed from dogs2
)
select species, mapref, breed
from animals
group by species, mapref, breed
This test script:
declare #entry table (nr int, refint int );
declare #map table (id int, name varchar(20) );
declare #cats table (mapRef int, breed varchar(20));
declare #dogs table (mapRef int, breed varchar(20));
insert #entry(nr,refint) values
(1,123)
,(2,456)
,(3,789)
,(4,123);
insert #map(id,name) values
(123,'dogs')
,(456,'cats')
,(789,'dogs');
insert #cats(mapRef,breed) values
(456,'bengal'),(888,'burma');
insert #dogs(mapRef,breed) values
(123,'sheepdog'), (999,'poodle');
with
cats2 as (
select species='cat', mapref, breed
from #cats animals
join #entry entry on entry.refint = animals.mapref
where entry.nr in (1,2,3,4)
),
dogs2 as (
select species='dog', mapref, breed
from #dogs animals
join #entry entry on entry.refint = animals.mapref
where entry.nr in (1,2,3,4)
),
animals as (
select species, mapref, breed from cats2
union all
select species, mapref, breed from dogs2
)
select species, mapref, breed
from animals
group by species, mapref, breed
yields as desired:
species mapref breed
------- ----------- --------------------
cat 456 bengal
dog 123 sheepdog
I have three tables , both with the same fields as in the example below:
Table:
dog
-------------
name, date
Table :
cat
-------------
name, date
Table:
animal
-------------
name, date
as I transfer the dog and cat data for animal table ? I tried the select into but could not do it with two tables.
Table value:
CAT
name date
Garfield 2015-08-03
DOG
name date
Spike 2015-08-03
Source:
insert into animal values ((select * from cat,dog))
Expected result
ANIMAL
name date
Garfield 2015-08-03
Spike 2015-08-03
Try this:
insert into animal
select name, date from dog
union all
select name, date from cat
It can be done with the execution of a query ie:Join operation.Table 1, Table 2,table 3. We have the same attribute in all these three tables.Just join the attributes with table1.fieldname JOIN table2.fieldname JOIN table3.fieldname
There is no need to do a JOIN as there is no relationship between them.
Insert Into animal (name, [date])
Select name, [date]
from dog, cat
Imagine I have two tables:
PETS
SPECIES
The SPECIES table has two columns:
ID - Species ID Number
DESCRIPTION - Description of the species (DOG, CAT, TURTLE, etc.)
The PETS table has two columns:
NAME - Name of the pet
SPECIES a link to the ID field of the SPECIES table
If I want a list of all pets named FLUFFY who are cats, I can do the following in a single SQL statement:
select *
from NAME, SPECIES
where PETS.NAME = 'FLUFFY'
and SPECIES.DESCRIPTION = 'CATS'
and PETS.SPECIES = SPECIES.ID
Now, I have a new pet, BOWSER, who's a dog. I want to be able to say something like this:
INSERT INTO PETS
(PETS.NAME, SPECIES.DESCRIPTION)
VALUES
('BOWSER', 'DOG')
Yes, I know I can first find the SPECIES.ID for DOG, then do the insert:
my $species = $sql.execute(select ID from SPECIES where description = 'DOG');
insert into PETS (NAME, SPECIES)
values ('BOWSER', '$species')
But, I want to do the insert with in a single SQL statement much the way I could do my query. Is that possible?
What about:
INSERT INTO Pets(Name, Species)
SELECT 'Bowser' AS Name, ID AS Species
FROM Species
WHERE Description = 'DOG';
You can use a subselect like:
INSERT INTO Pets (
Name,
Species
) VALUES (
'Bowser',
(SELECT Id FROM Species WHERE Description='Dog')
)
INSERT INTO PETS
(
NAME,
SPECIES
)
SELECT
'BOWSER',
ID
FROM
SPECIES
WHERE
DESCRIPTION='DOG'