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
Related
I have a table that stores pets and a certain number of vaccines. In one column the identifier, in another column the name of the vaccine and in the third column, the date of completion. In case the date is null, it means that the pet has not received that vaccine yet.
This estructure is the next one:
CREATE TABLE pets (
pet VARCHAR (10),
vaccine VARCHAR (50),
complete_date DATE
);
INSERT INTO pets VALUES ('DOG001', 'Adenovirus', '2021-01-03');
INSERT INTO pets VALUES ('DOG001', 'Parvovirus', '2021-02-03');
INSERT INTO pets VALUES ('DOG001', 'Leptospirosis', null);
INSERT INTO pets VALUES ('CAT774', 'Calcivirosis', '2021-01-06');
INSERT INTO pets VALUES ('CAT774', 'Panleukopenia', null);
INSERT INTO pets VALUES ('DOG002', 'Adenovirus', '2020-12-21');
INSERT INTO pets VALUES ('DOG002', 'Parvovirus', '2021-02-01');
INSERT INTO pets VALUES ('DOG002', 'Leptospirosis', '2021-03-01');
pet
vaccine
complete_date
DOG001
Adenovirus
2021-01-03
DOG001
Parvovirus
2021-02-03
DOG001
Leptospirosis
null
CAT774
Calcivirosis
2021-01-06
CAT774
Panleukopenia
null
DOG002
Adenovirus
2020-12-21
DOG002
Parvovirus
2021-02-01
DOG002
Leptospirosis
2021-03-01
What I need is a list of all the pets that do not have a null "date", considering all the vaccines.
In this example, the result should be simply 'DOG002' since it is the only animal with all its dates with non-null values.
A conditional aggregate in the HAVING would be one method:
SELECT Pet
FROM dbo.Pets
GROUP BY Pet
HAVING COUNT(CASE WHEN Complete_Date IS NULL THEN 1 END) = 0;
I think Larnu posted what you are looking for (+1)... BUT... just in case you want to see the pet's details.
Just another option is WITH TIES.
Select top 1 with ties *
From pets
order by sum(case when complete_date is null then 1 else 0 end) over (partition by pet)
SELECT DISTINCT Pet FROM Pets
WHERE Pet NOT IN (SELECT Pet FROM Pets WHERE Complete_Date IS NULL)
CTE can also be used to achieve the above result
with CTE as
(
select pet,
vaccine,
complete_date,
SUM(IIF(complete_date is null ,1,0)) over (PARTITION BY pet) as pet_flag
from pets
)
select distinct Pet from CTE where
pet_flag = 0
I have two tables, Table A and Table B that I am trying to extract information from and create a resulting table.
Table A
user_ids value
{user_123, user_234} apples
{user_456, user_123} oranges
{user_234} kiwi
Table B
id name
123 John Smith
234 Jane Doe
456 John Doe
I want to join the two tables in a way that will result in the following:
Table C
user_ids value user_names
{user_123, user_234} apples {John Smith, Jane Doe}
{user_456, user_123} oranges {John Doe, John Smith}
{user_234} kiwi {Jane Doe}
Any help would be really appreciated!
Others have already encouraged you to normalize your design and there are numerous posts on why this is recommended. Using your current shared dataset, the following was done using postgres where the user_ids was treated as a text array. I also tested with the user_ids as text as used cast(user_ids as text[]) to convert it to a text array
See fiddle and result below:
Schema (PostgreSQL v11)
CREATE TABLE table_a (
"user_ids" text[],
"value" VARCHAR(7)
);
INSERT INTO table_a
("user_ids", "value")
VALUES
('{user_123, user_234}', 'apples'),
('{user_456, user_123}', 'oranges'),
('{user_234}', 'kiwi');
CREATE TABLE table_b (
"id" INTEGER,
"name" VARCHAR(10)
);
INSERT INTO table_b
("id", "name")
VALUES
('123', 'John Smith'),
('234', 'Jane Doe'),
('456', 'John Doe');
The first CTE user_values creates a row for each user_id and value. The second CTE merged_values joins table_b on the pattern user_<user_id> if it exists and ensures unique results using DISTINCT. The final projection groups based on values and users array_agg to collect all user_ids or names into a single row.
Query #1
WITH user_values AS (
SELECT
unnest(a.user_ids) user_id,
a.value
FROM
table_a a
),
merged_values AS (
SELECT DISTINCT
a.user_id,
a.value,
b.name
FROM
user_values a
LEFT JOIN
table_b b ON a.user_id = CONCAT('user_',b.id)
)
SELECT
array_agg(user_id) user_ids,
value,
array_agg(name) "names"
FROM
merged_values
GROUP BY
value;
user_ids
value
names
user_123,user_456
oranges
John Smith,John Doe
user_123,user_234
apples
John Smith,Jane Doe
user_234
kiwi
Jane Doe
View on DB Fiddle
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 have a simplified table that shows my problem
Name Animal
Bill Dog
Bill Cat
Bill Fish
John Cat
John Fish
Sara Dog
Sara Cat
Mark Fish
I want the number of people that have no dog. I tried this query.
select count(distinct Name) from Table
where Animal <> 'Dog'
But it returns 4 and not the expected 2. What am I doing wrong?
Your query returned the count of names that have any animal other than dog.
select distinct name
from table t1
where not exists
(
select 1 from table t2 where t1.name=t2.name and t2.Animal='Dog'
)
Use not exists :
select count(distinct t.name) as counts
from table t
where not exists (select 1 from table where name = t.name and animal = 'Dog');
For your current query you are filtering single record based on animal name which would not produced desired result as it should be along with name column.
your where condition "Animal <> 'dog'" is filtering the rows not the names.
So try the below query
Select count(distinct Name) from Table where name not in (
select Name from Table where Animal = 'Dog')
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