Related
I have three statements. If any of them returns anything I want that to be returned and the query to exit.
select *
from connexion
where origin = 'Stockholm'
and destination = 'Berlin';
-- IF IT RETURNS ONE OR MORE ROWS THEN RETURN ROW/ROWS AND EXIT, ELSE GO TO STATEMENT BELOW
select *
from connexion c1, connexion c2
where c1.origin = 'Stockholm'
and c2.destination = 'Berlin'
and c1.destination = c2.origin;
-- IF IT RETURNS ONE OR MORE ROWS THEN RETURN ROW/ROWS AND EXIT, ELSE GO TO STATEMENT BELOW
select *
from connexion c1, connexion c2, connexion c3
where c1.origin = 'Stockholm'
and c3.destination = 'Berlin'
and c1.destination = c2.origin
and c2.destination = c3.origin;
-- IF IT RETURNS ONE OR MORE ROWS THEN RETURN ROW/ROWS AND EXIT, ELSE EXIT
Here's the query to create the database. I want to retrieve a result where I can go from Stockholm to Berlin via any of the available connexions.
create table busstop(
city varchar(50),
country varchar(50) not null,
streetAddress varchar(50) not null,
primary key (city)
);
create table driver(
driverPnr varchar(13),
name varchar(50) not null,
address varchar(50) not null,
phone varchar(12) not null,
primary key (driverPnr)
);
create table customer(
customerPnr varchar(13),
name varchar(50) not null,
email varchar(50) not null,
phone varchar(12) not null,
primary key (customerPnr)
);
create table connexion(
connexionId serial not null,
origin varchar(50) not null,
destination varchar(50) not null,
primary key (connexionId),
foreign key (origin) references busstop(city),
foreign key (destination) references busstop(city)
);
create table trip(
tripId serial not null,
connexionId integer not null,
departure timestamp not null,
arrival timestamp not null,
driverPnr varchar(13),
priceAmount integer not null,
seats integer not null,
primary key (tripId),
foreign key (connexionId) references connexion(connexionId),
foreign key (driverPnr) references driver(driverPnr)
);
create table booking(
customerPnr varchar(13) not null,
tripId integer not null,
seats integer not null,
primary key (customerPnr, tripId),
foreign key (customerPnr) references customer(customerPnr),
foreign key (tripId) references trip(tripId)
);
insert into busstop(city, country, streetAddress) values
('Stockholm', 'Sweden', 'Byvägen 1'),
('Copenhagen', 'Denmark', 'Vesterbrogade 23'),
('Berlin', 'Germany', 'Europaplatz 4'),
('Amsterdam', 'Netherlands', 'Stationsplein 17'),
('Prague', 'Czech Republic', 'Wilsonova 10');
insert into connexion(origin, destination) values
('Stockholm', 'Copenhagen'),
('Copenhagen', 'Stockholm'),
('Copenhagen', 'Berlin'),
('Berlin', 'Copenhagen'),
('Copenhagen', 'Amsterdam'),
('Amsterdam', 'Copenhagen'),
('Berlin', 'Prague'),
('Prague', 'Berlin'),
('Amsterdam', 'Berlin'),
('Berlin', 'Amsterdam'),
('Amsterdam', 'Prague'),
('Prague', 'Amsterdam');
insert into trip(connexionId, departure, arrival, priceAmount, seats) values
-- Exits on 2018-04-21
-- Stockholm - Copenhagen / Copenhagen - Stockholm, 3 hours
(1, '2018-04-22 07:00:00', '2018-04-22 10:00:00', 200, 35),
(2, '2018-04-22 18:00:00', '2018-04-22 21:00:00', 200, 35),
-- Copenhagen - Berlin / Berlin - Copenhagen, 7 hours
(3, '2018-04-22 10:00:00', '2018-04-22 17:00:00', 500, 35),
(4, '2018-04-22 11:00:00', '2018-04-22 18:00:00', 500, 35),
-- Copenhagen - Amsterdam / Amsterdam - Copenhagen, 9 hours
(5, '2018-04-22 10:00:00', '2018-04-22 19:00:00', 800, 35),
(6, '2018-04-22 09:00:00', '2018-04-22 18:00:00', 800, 35),
-- Berlin - Prague / Prague - Berlin, 4 hours
(7, '2018-04-22 17:00:00', '2018-04-22 21:00:00', 300, 35),
(8, '2018-04-22 07:00:00', '2018-04-22 11:00:00', 300, 35),
-- Amsterdam - Berlin / Berlin - Amsterdam, 7 hours
(9, '2018-04-22 07:00:00', '2018-04-22 14:00:00', 500, 35),
(10, '2018-04-22 14:00:00', '2018-04-22 21:00:00', 500, 35),
-- Amsterdam - Prague / Prague - Amsterdam, 9 hours
(11, '2018-04-22 05:00:00', '2018-04-22 14:00:00', 800, 35),
(12, '2018-04-22 14:00:00', '2018-04-22 23:00:00', 800, 35);
If I go from Stockholm to Berlin the query has to first check if there are any direct connexions between Stockholm and Berlin. If no, then it has to check if there are any connexion with ONE stopover, if so retrieve a row for that. If there's none, proceed with checking if there's any connexion with TWO stopovers, and it continues until it has checked THREE stopovers. (no one would want to travel from Stockholm to Berlin with more than three stopovers..).. It's so hard to explain what I want to achieve but I hope you get the point :)
You can do this with multiple joins:
select c1.*, c2.*, c3.*
from connexion c1 left join
connexion c2
on c1.origin = 'Stockholm' and
(c1.destination = 'Berlin' or
(c1.destination <> 'Berlin' and c2.destination = 'Berlin')
) left join
connection c3
on c2.destination = c3.destination and
(c2.destination <> 'Berlin' and
c1.destination <> 'Berlin'
);
a reach and this is tsql
this is just direct or 1 stop
select 'Stockholm' as origin_, 'Berlin' as destination_, *
from connexion c1
join connexion c2
on c1.origin = 'Stockholm'
and ( c1.destination = 'Berlin'
or (c1.destination <> 'Berlin' and c2.destination = 'Berlin')
)
This is sql server but according to the docs postgresql supports recursion.
Stop is just the last stop. This does not show you all stops. Cnt is the number of stops.
declare #t table (orig varchar(20), dest varchar(20)
, primary key (orig, dest));
insert into #t values
('Stockholm', 'Copenhagen'),
('Copenhagen', 'Stockholm'),
('Copenhagen', 'Berlin'),
('Berlin', 'Copenhagen'),
('Copenhagen', 'Amsterdam'),
('Amsterdam', 'Copenhagen'),
('Berlin', 'Prague'),
('Prague', 'Berlin'),
('Amsterdam', 'Berlin'),
('Berlin', 'Amsterdam'),
('Amsterdam', 'Prague'),
('Prague', 'Amsterdam');
with cte as
( select t.orig, t.orig as 'stop', t.dest, 1 as cnt
from #t t
union all
select cte.orig, t.orig, t.dest, cnt + 1
from #t t
join cte
on cte.dest = t.orig
and t.dest <> cte.orig --don't loop back home
and cnt < 4
)
select *
from cte
where orig = 'Stockholm'
and dest = 'Berlin'
order by cnt, cte.stop
This will not prevent looping in route. By limiting cnt the loops are eliminated. It prevents going back to the original city.
You can use GOTo Statement in SQL . In below code you can assign your query counts and then in if condition you can count if its grater than 0 then GOTO respective query.
DECLARE #a Int
DECLARE #b Int
SELECT #a = 10
SELECT #b = 5
BEGIN
IF #a>#0 GOTO Greater
IF #b>0 GOTO Lesser
END
Greater: SELECT #a
Lesser: SELECT #b
I've been trying to figure out this question all day, I've created a table and trying to make a Select statement that would answer this question
Who are the mothers in the Simpsons family tree? List them from oldest
to youngest.
With my current data I don't know how I would go about doing this with only one table.
CREATE TABLE person
(
persID INT IDENTITY(1,1),
persFName VARCHAR(40) NOT NULL,
persLName VARCHAR(40) NOT NULL,
persGender CHAR(1) NOT NULL,
persDOB DATE NOT NULL,
persDOD DATE ,
fatherID INT ,
motherID INT ,
CONSTRAINT pk_person_persID PRIMARY KEY(persID),
CONSTRAINT fk_person_fatherID FOREIGN KEY (fatherID) REFERENCES person(persID),
CONSTRAINT fk_person_motherID FOREIGN KEY (motherID) REFERENCES person(persID),
);
And this is my data
INSERT INTO person(persFName,persLname,persGender,persDOB,persDOD,fatherID,motherID) VALUES ('Abraham', 'Simpson', 'M', '1944-01-15', '2015-07-21',NULL,NULL)
INSERT INTO person(persFName,persLname,persGender,persDOB,persDOD,fatherID,motherID) VALUES ('Mona', 'Simpson', 'F', '1946-09-22', NULL,NULL,NULL)
INSERT INTO person(persFName,persLname,persGender,persDOB,persDOD,fatherID,motherID) VALUES ( 'Herb', 'Simpson', 'M', '1963-11-21',NULL,1,2)
INSERT INTO person(persFName,persLname,persGender,persDOB,persDOD,fatherID,motherID) VALUES ( 'Homer', 'Simpson', 'M', '1965-05-19',NULL,1,2)
INSERT INTO person(persFName,persLname,persGender,persDOB,persDOD,fatherID,motherID) VALUES ( 'Clancy', 'Bouvier', 'F', '1945-02-12',NULL,NULL,NULL)
INSERT INTO person(persFName,persLname,persGender,persDOB,persDOD,fatherID,motherID) VALUES ( 'Jackie', 'Bouvier', 'M', '1945-12-01','2016-05-15',NULL,NULL)
INSERT INTO person(persFName,persLname,persGender,persDOB,persDOD,fatherID,motherID) VALUES ( 'Marge', 'Simpson', 'F', '1966-05-18',NULL,6,5)
INSERT INTO person(persFName,persLname,persGender,persDOB,persDOD,fatherID,motherID) VALUES ( 'Patty', 'Bouvier', 'F', '1964-01-08',NULL,6,5)
INSERT INTO person(persFName,persLname,persGender,persDOB,persDOD,fatherID,motherID) VALUES ( 'Selma', 'Bouvier', 'F', '1969-03-01',NULL,6,5)
INSERT INTO person(persFName,persLname,persGender,persDOB,persDOD,fatherID,motherID) VALUES ( 'Bart', 'Simpson', 'M', '1990-01-01',NULL,4,7)
INSERT INTO person(persFName,persLname,persGender,persDOB,persDOD,fatherID,motherID) VALUES ( 'Lisa', 'Simpson', 'F', '1992-05-15',NULL,4,7)
INSERT INTO person(persFName,persLname,persGender,persDOB,persDOD,fatherID,motherID) VALUES ( 'Maggie', 'Simpson', 'F', '1997-11-28',NULL,4,7)
INSERT INTO person(persFName,persLname,persGender,persDOB,persDOD,fatherID,motherID) VALUES ( 'Ling', 'Bouvier', 'M', '2000-04-02',NULL,NULL,9)
Try this:
SELECT *
FROM person
WHERE persID IN (SELECT DISTINCT motherID FROM person)
AND persLNAme = 'Simpson'
ORDER BY persDOB ASC;
The idea is to get all mothers' IDs and then to extract them from the base table. Then we are using ORDER BY clause to sort the result.
This should give you what you are looking for but I am not sure if it is the smartest way! I hope this help.
SELECT DISTINCT T2.motherID,
T1.persID,
T1.PersFName,
T1.PersLName,
T1.PersGender,
T1.PersDOB,
T1.PersDOD,
T1.FatherID,
T1.MotherID
FROM person AS T1
LEFT JOIN person AS T2 ON T1.persID = T2.motherID
WHERE T2.motherID IS NOT NULL
AND T1.persLName = 'Simpson'
ORDER BY T1.persDOB
I've written the code below and keep getting an error for incorrect syntax
It said at line 10 near the , - so this line:
values(1, 'Stolz', 'Ted', 25000, NULL), )
If I only try to insert the first row of data it works fine, it's when I try to do multiple. Am I missing something really simple?
Drop Table #TPerson
CREATE TABLE #TPerson
(
personid int PRIMARY KEY NOT NULL,
lastname varchar(50) NULL,
firstname varchar(50) NULL,
salary money NULL,
managerid int NULL
);
Insert Into #TPerson(Personid, lastname, firstname, salary, managerid)
values (1, 'Stolz', 'Ted', 25000, NULL),
(2, 'Boswell', 'Nancy', 23000, 1),
(3, 'Hargett', 'Vincent', 22000, 1),
(4, 'Weekley', 'Kevin', 22000, 3),
(5, 'Metts', 'Geraldine', 22000, 2),
(6, 'McBride', 'Jeffrey', 21000, 2),
(7, 'Xiong', 'Jay', 20000, 3)
You can write something like this:
Insert Into #TPerson(Personid,lastname,firstname,salary,managerid)
select 1,'Stolz','Ted',25000,NULL
union all select 2,'Boswell','Nancy',23000,1
union all select 3,'Hargett','Vincent',22000,1
union all select 4,'Weekley','Kevin',22000,3
union all select 5,'Metts','Geraldine',22000,2
union all select 6,'McBride','Jeffrey',21000,2
union all select 7,'Xiong','Jay',20000,3
I have the following two tables (SQL scripts with data):
CREATE TABLE [dbo].[Item_Master](
[Item_Name] [varcha`enter code here`r](20) NOT NULL,
[Item_Cost] [int] NULL,
CONSTRAINT [PK_Item_Master] PRIMARY KEY CLUSTERED
(
[Item_Name] ASC
)
)
GO
CREATE TABLE [dbo].[ItemAnalysis]
(
Item_Name nvarchar(20) NOT NULL,
Analysis_Type nvarchar(20) NOT NULL,
Item_Quantity int NOT NULL,
Analysis_Date date NOT NULL
)
GO
insert Item_Master (Item_Name, Item_Cost)
values ('item1', 2)
insert Item_Master (Item_Name, Item_Cost)
values ('item2', 3)
insert ItemAnalysis (Item_Name, Analysis_Type, Item_Quantity, Analysis_Date)
values ('item1', 'A', 10, '2012-01-14')
insert ItemAnalysis (Item_Name, Analysis_Type, Item_Quantity, Analysis_Date)
values ('item1', 'B', 12, '2012-01-14')
insert ItemAnalysis (Item_Name, Analysis_Type, Item_Quantity, Analysis_Date)
values ('item2', 'A', 11, '2012-01-14')
insert ItemAnalysis (Item_Name, Analysis_Type, Item_Quantity, Analysis_Date)
values ('item2', 'B', 14, '2012-01-14')
insert ItemAnalysis (Item_Name, Analysis_Type, Item_Quantity, Analysis_Date)
values ('item1', 'A', 9, '2012-02-11')
insert ItemAnalysis (Item_Name, Analysis_Type, Item_Quantity, Analysis_Date)
values ('item1', 'B', 11, '2012-02-11')
insert ItemAnalysis (Item_Name, Analysis_Type, Item_Quantity, Analysis_Date)
values ('item2', 'A', 20, '2012-02-11')
insert ItemAnalysis (Item_Name, Analysis_Type, Item_Quantity, Analysis_Date)
values ('item2', 'B', 7, '2012-02-11')
I need the output like this:
Item_Name| Item_Cost| Analysis_Date| Type_A_Quantity| Type_B_Quantity
----------------------------------------------------------------------
item1|2|2012-01-14|10|12
item2|3|2012-01-14|11|14
item1|2|2012-02-11|9|11
item2|3|2012-02-11|20|7
There is no regularity on when the analysis would be done (e.g. it cal be done weekly or monthly etc) but whenever the analysis is done it is done for all the items on a single day.
SQL Fiddle
SELECT
m.Item_Name,
m.Item_Cost,
a.Analysis_Date,
SUM(CASE WHEN Analysis_Type = 'A' THEN Item_Quantity ELSE 0 END) as Type_A_Quantity,
SUM(CASE WHEN Analysis_Type = 'B' THEN Item_Quantity ELSE 0 END) as Type_B_Quantity
FROM Item_Master m
JOIN ItemAnalysis a
ON m.Item_Name = a.Item_Name
GROUP BY m.Item_Name, m.Item_Cost, a.Analysis_Date
I have two MySql tables as shown below with the data shown:
CREATE TABLE `A` (
`id` int(12) NOT NULL AUTO_INCREMENT,
`status` varchar(50) DEFAULT NULL,
`another_field` varchar(50) DEFAULT NULL
)
INSERT INTO `A` VALUES ('1', null, 'a');
INSERT INTO `A` VALUES ('2', null, 'b');
INSERT INTO `A` VALUES ('3', null, 'c');
CREATE TABLE `B` (
`id` int(12) NOT NULL AUTO_INCREMENT,
`status` varchar(50) DEFAULT NULL,
`tableA_id` int(12) DEFAULT NULL,
PRIMARY KEY (`id`)
)
INSERT INTO `B` VALUES ('1', 'aa', '1');
INSERT INTO `B` VALUES ('2', 'aa', '1');
INSERT INTO `B` VALUES ('3', 'aa', '2');
INSERT INTO `B` VALUES ('4', 'aa', '3');
INSERT INTO `B` VALUES ('5', 'bb', '3');
I want to know if it is possible to update A.status if all B.status are the same when A.id = B.tableA_id using a single query?
This is what I want my table A to look like:
('1', 'aa', 'a') - Status is updated to 'aa' as B.id 1 & 2 have the same status and same B.tableA_id value.
('2', 'aa', 'b') - Status is updated to 'aa' as B.id 3 has the same status.
('3', null, 'c') - This is not updated because B.id 4 & 5 have different status and the same table2.table1_id value.
Thanks
UPDATE A
SET status = COALESCE((
SELECT MAX(B.status)
FROM B
WHERE B.tableA_id = A.id
HAVING MAX(B.status) = MIN(B.status)
), A.status)
(Note: I added a correction, you need the COALESCE(..., A.status) or otherwise the status will be set to NULL in case there were multiple statuses in B
Not sure about MySql but in MSSQL you could write something like:
UPDATE A SET A.Status = 'aa'
FROM A INNER JOIN B on A.id = B.tableA_id
WHERE b.status = 'aa'
It should be similar in MySQL, but I'm not if the language supports joins on update. But still I hope it helps.
UPDATE a SET status =
(
SELECT status FROM b WHERE tableA_id = a.id LIMIT 0,1
)
WHERE id IN
(
SELECT tableA_id FROM b
GROUP BY tableA_id
HAVING COUNT(DISTINCT status) = 1
)
Update: Roland was right; I have updated the query and it now yields the correct results.
CREATE TABLE `A` (
`id` int(12) NOT NULL AUTO_INCREMENT,
`status` varchar(50) DEFAULT NULL,
`another_field` varchar(50) DEFAULT NULL
)
INSERT INTO `A` VALUES ('1', null, 'a');
INSERT INTO `A` VALUES ('2', null, 'b');
INSERT INTO `A` VALUES ('3', null, 'c');
CREATE TABLE `B` (
`id` int(12) NOT NULL AUTO_INCREMENT,
`status` varchar(50) DEFAULT NULL,
`tableA_id` int(12) DEFAULT NULL,
PRIMARY KEY (`id`)
)
INSERT INTO `B` VALUES ('1', 'aa', '1');
INSERT INTO `B` VALUES ('2', 'aa', '1');
INSERT INTO `B` VALUES ('3', 'aa', '2');
INSERT INTO `B` VALUES ('4', 'aa', '3');
INSERT INTO `B` VALUES ('5', 'bb', '3');