I have a database with the following structure with the following registers
CREATE TABLE aircraft (
number_aircraft int(11) ,
type_aircraft VARCHAR(10),
PRIMARY KEY ( number_aircraft )
);
CREATE TABLE passenger (
number_flight int(11) ,
ID int(11),
Name char(10) DEFAULT NULL,
PRIMARY KEY ( number_flight , ID ),
FOREIGN KEY ( number_flight ) REFERENCES flight ( number_flight )
);
CREATE TABLE flight (
number_flight int(11) ,
since char(2) ,
until char(2) ,
Date_flight date ,
number_aircraft int(11),
PRIMARY KEY ( number_flight,number_aircraft ),
FOREIGN KEY ( number_aircraft ) REFERENCES aircraft ( number_aircraft )
);
INSERT INTO aircraft ( number_aircraft , type_aircraft ) VALUES (1,'B-777');
INSERT INTO aircraft ( number_aircraft , type_aircraft ) VALUES (2,'B-755');
INSERT INTO aircraft ( number_aircraft , type_aircraft ) VALUES (3,'B-775');
INSERT INTO aircraft ( number_aircraft , type_aircraft ) VALUES (4,'B-505');
INSERT INTO aircraft ( number_aircraft , type_aircraft ) VALUES (5,'Airbus A3');
INSERT INTO aircraft ( number_aircraft , type_aircraft ) VALUES (6,'B-707');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (1,34889876,'German');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (1,44859776,'Ariel');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (2,34587880,'Andres');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (2,34886463,'David');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (3,24757385,'Juan');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (3,34885768,'Marcos');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (4,10000001,'Bárbara');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (4,20000002,'Daniela');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (5,20000003,'Alejandra');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (5,20000004,'Melina');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (6,30000001,'Daniela');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (6,30000002,'Valeria');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (7,40000001,'Silvana');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (7,50000001,'Cecilia');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (8,50000002,'Noelia');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (8,50000003,'Cintia');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (9,60000001,'Mariela');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (9,60000002,'Ornella');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (10,60000003,'Cecilia');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (10,60000004,'Valeria');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (11,60000005,'Agustina');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (11,60000006,'Aldana');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (12,60000007,'Carolina');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (12,60000008,'Cecilia');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (13,70000001,'Bárbara');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (13,70000002,'Gisele');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (14,70000003,'Cecilia');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (14,70000004,'Vicuntilria');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (15,60000009,'Sabrina');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (15,60000010,'Agostina');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (16,80000001,'Andrea');
INSERT INTO passenger ( number_flight , ID , Name ) VALUES (16,80000002,'Tamara');
INSERT INTO flight ( number_flight , since , Until , Date_flight , number_aircraft ) VALUES (1,'A','A','2001-02-14',1);
INSERT INTO flight ( number_flight , since , Until , Date_flight , number_aircraft ) VALUES (2,'A','F','2010-05-15',1);
INSERT INTO flight ( number_flight , since , Until , Date_flight , number_aircraft ) VALUES (3,'A','D','2012-08-09',4);
INSERT INTO flight ( number_flight , since , Until , Date_flight , number_aircraft ) VALUES (4,'B','H','2001-02-14',3);
INSERT INTO flight ( number_flight , since , Until , Date_flight , number_aircraft ) VALUES (5,'D','H','2005-06-17',4);
INSERT INTO flight ( number_flight , since , Until , Date_flight , number_aircraft ) VALUES (6,'A','D','2007-03-17',1);
INSERT INTO flight ( number_flight , since , Until , Date_flight , number_aircraft ) VALUES (7,'A','F','2001-02-19',2);
INSERT INTO flight ( number_flight , since , Until , Date_flight , number_aircraft ) VALUES (8,'C','F','2011-03-14',2);
INSERT INTO flight ( number_flight , since , Until , Date_flight , number_aircraft ) VALUES (9,'A','B','2013-03-02',4);
INSERT INTO flight ( number_flight , since , Until , Date_flight , number_aircraft ) VALUES (10,'A','B','2010-03-12',3);
INSERT INTO flight ( number_flight , since , Until , Date_flight , number_aircraft ) VALUES (11,'A','D','2011-04-28',3);
INSERT INTO flight ( number_flight , since , Until , Date_flight , number_aircraft ) VALUES (12,'C','B','2013-01-01',4);
INSERT INTO flight ( number_flight , since , Until , Date_flight , number_aircraft ) VALUES (13,'B','D','2013-03-21',5);
INSERT INTO flight ( number_flight , since , Until , Date_flight , number_aircraft ) VALUES (14,'A','B','2012-03-02',5);
INSERT INTO flight ( number_flight , since , Until , Date_flight , number_aircraft ) VALUES (15,'D','H','2013-06-06',6);
INSERT INTO flight ( number_flight , since , Until , Date_flight , number_aircraft ) VALUES (16,'A','H','2013-12-13',6);
I have to list the average number of passengers transported by aircraft
company, by aircraft type, as I do? attempt to use the avg () but
I do not use it when I have a join.
If I understand you correctly, this should do it, simpler done using two COUNT DISTINCT instead of AVG; (sorry, with the original question's names)
SELECT a.Tipo_avion, COUNT(DISTINCT p.Documento)/COUNT(DISTINCT v.Nro_vuelo) avg_passengers
FROM vuelo v
LEFT JOIN pasajero p
ON v.Nro_Vuelo = p.Nro_Vuelo
LEFT JOIN avion a
ON v.Nro_Avion = a.Nro_Avion
GROUP BY a.Tipo_avion
An SQLfiddle to test with.
Related
For better understanding please find the attached image (For detailed information please click here)
Condition:
value_string/Value_Float column field value present i.e Greater than 0, consider as Start_DateTime, next row have same value don’t consider that value just ignore that field. else next row it consists different value consider that one as start_datetime.
If value_string/Value_Float column field value 0,consider as End_Time,In every Group if First Value 0 don’t consider.after the start_Datetime arrived 0 considered as End_dateTime
If the group does not finish with 0(End_dateTime) show the field as 'Null'(Example Group C)
Source Table:
Desired Result
Create Table
CREATE TABLE [dbo].[Activity]
(
[DateTime] [datetime] NULL,
[Group] [nvarchar](255) NULL,
[Value_String] [float] NULL,
[Value_Float] [float] NULL
)
Insert values
Insert INTO [Activity] VALUES ( '2021-06-23 11:32.000','A','0',0)
Insert INTO [Activity] VALUES ( '2021-06-23 12:13.000','A','1',1)
Insert INTO [Activity] VALUES ( '2021-06-23 17:25.000','A','0',0)
Insert INTO [Activity] VALUES ( '2021-06-24 07:32.000','A','12',12)
Insert INTO [Activity] VALUES ( '2021-06-24 11:30.000','A','0',0)
Insert INTO [Activity] VALUES ( '2021-06-23 05:02.000','B','15',15)
Insert INTO [Activity] VALUES ( '2021-06-23 06:20.000','B','0',0)
Insert INTO [Activity] VALUES ( '2021-06-23 08:16.000','B','5',5)
Insert INTO [Activity] VALUES ( '2021-06-24 19:12.000','B','5',5)
Insert INTO [Activity] VALUES ( '2021-06-24 23:29.000','B','0',0)
Insert INTO [Activity] VALUES ( '2021-06-23 11:42.000','C','0',0)
Insert INTO [Activity] VALUES ( '2021-06-23 13:20.000','C','4',4)
Insert INTO [Activity] VALUES ( '2021-06-23 16:15.000','C','0',0)
Insert INTO [Activity] VALUES ( '2021-06-24 17:52.000','C','4',4)
Insert INTO [Activity] VALUES ( '2021-06-24 23:12.000','C','4',4)
Insert INTO [Activity] VALUES ( '2021-06-23 11:32.000','D','17',17)
Insert INTO [Activity] VALUES ( '2021-06-23 13:47.000','D','15',15)
Insert INTO [Activity] VALUES ( '2021-06-23 16:48.000','D','0',0)
Insert INTO [Activity] VALUES ( '2021-06-24 17:32.000','D','24',24)
Insert INTO [Activity] VALUES ( '2021-06-24 19:32.000','D','0',0)
…
select min([Datetime]) as startdt, max(next0datetime) as enddt, [Group], Value_String, Value_Float
from
(
select *, sum(addme) over(partition by [Group] order by [DateTime]) as grpid
from
(
select *,
min(case when Value_String = '0' then [Datetime] end) over(partition by [Group] order by [DateTime] rows between 1 following and unbounded following)
as next0datetime,
case when Value_String <> lag(Value_String) over(partition by [Group] order by [DateTime]) then 1 else 0 end as addme
from dbo.Activity
) as a
) as g
where Value_String <> '0'
group by [Group], grpid, Value_String, Value_Float
order by [Group], startdt, enddt;
It's quite hard for me to write nice title, so I'll try to describe the problem here in detail.
We have table [dbo].[LEASE_APPLICATIONS_AUDIT_LOG] that stores the historical data with changed datetimes. In case if the status of the data was NOT IN ('E', 'F', 'I', 'O', 'X') then that means that it was approved at that moment and if the status is other than these ones, then it is not approved. It can become approved and not approved in any order and many times. For example:
'2010.01.01', 'A'
'2010.02.01', 'B'
'2010.03.01', 'E'
'2010.04.01', 'Z'
That means that the record was approved from 2010.01.01 till 2010.03.01 and then was approved again at 2010.04.01.
There is another table [dbo].[LEASE_FINANCING_AUDIT_LOG] that stores the base payment amount that was at that time. For example if for the same record I would have such entries:
'2010.01.01', 123
'2010.04.01', 321
then that means that from base payment was 123 from 2010.01.01 till 2010.03.01 (became unapproved) and then from 2010.04.01 the value became to be 321.
There could be various combination of status changes and there could be different base payment values at any period of times.
So, the goal is to find the LATEST base_payment value that was in between APPROVED period.
Here are the scripts we've made so far. There are 2 tables with that data and the function. Other code snippets are taken from unit tests that's why they are like that and they will output 'bad' string if the logic is not as expected one. The function is working, but I do not really like the TOP 1/ORDER BY approach and trying to find if there is better way to achieve that. Any thoughts?
SET NOCOUNT ON;
CREATE TABLE [dbo].[LEASE_APPLICATIONS_AUDIT_LOG]
(
[LEASE_APPLICATION] CHAR(8)
, [APPLICATION_STATUS_CODE] CHAR(1)
, [CHANGED_DATE] DATETIME2(7) NOT NULL
);
GO
CREATE TABLE [dbo].[LEASE_FINANCING_AUDIT_LOG]
(
[LEASE_APPLICATION] CHAR(8)
, [BASE_PAYMENT] DECIMAL(10, 2) NULL
, [CHANGED_DATE] DATETIME2(7) NOT NULL
);
GO
CREATE FUNCTION [dbo].[post_approval_payment_amount] (#lease_application CHAR(8))
RETURNS TABLE
AS
RETURN (
SELECT TOP 1 lfal.BASE_PAYMENT AS post_approval_payment_amount
FROM LEASE_APPLICATIONS_AUDIT_LOG laal
CROSS APPLY
(
SELECT TOP 1 lf.BASE_PAYMENT
FROM LEASE_FINANCING_AUDIT_LOG lf
WHERE lf.LEASE_APPLICATION = laal.LEASE_APPLICATION
AND lf.CHANGED_DATE < COALESCE((
SELECT TOP 1 la.CHANGED_DATE
FROM LEASE_APPLICATIONS_AUDIT_LOG la
WHERE la.LEASE_APPLICATION = laal.LEASE_APPLICATION
AND la.CHANGED_DATE > laal.CHANGED_DATE
ORDER BY la.CHANGED_DATE
), CAST('9999-12-31 23:59:59' AS DATETIME))
ORDER BY lf.CHANGED_DATE DESC
) lfal
WHERE laal.LEASE_APPLICATION = #lease_application
AND laal.APPLICATION_STATUS_CODE NOT IN ('E', 'F', 'I', 'O', 'X')
ORDER BY laal.CHANGED_DATE DESC
);
GO
DECLARE #lease_application CHAR(8) = '35163328'
, #base_payment DECIMAL = 209.12
, #expected DECIMAL = 209.12
, #actual DECIMAL;
DECLARE #la AS TABLE
(
change_date DATETIME2(7)
, application_status_code CHAR(1) NULL
, base_amount DECIMAL NULL
, is_laal BIT
);
INSERT INTO #la ( change_date
, application_status_code
, base_amount
, is_laal
)
VALUES ('2017-05-11 03:46:26.4800000', 'K', NULL, 1)
, ('2017-05-11 03:48:05.0600000', NULL, #base_payment, 0)
, ('2017-06-21 14:07:51.2200000', 'X', NULL, 1);
INSERT INTO dbo.lease_applications_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, APPLICATION_STATUS_CODE
)
SELECT #lease_application
, l.change_date
, l.application_status_code
FROM #la AS l
WHERE l.is_laal = 1;
INSERT INTO dbo.lease_financing_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, BASE_PAYMENT
)
SELECT #lease_application
, l.change_date
, l.base_amount
FROM #la AS l
WHERE l.is_laal = 0;
SELECT #actual = post_approval_payment_amount
FROM [dbo].[post_approval_payment_amount](#lease_application);
IF (#expected <> #actual) SELECT 'Test 1 failed'
ELSE SELECT 'Test 1 passed';
SELECT #lease_application = '30000152'
, #base_payment = 622.15
, #expected = 622.15;
DELETE FROM #la;
INSERT INTO #la ( change_date
, application_status_code
, base_amount
, is_laal
)
VALUES ('2017-05-11 03:46:26.4800000', 'z', NULL, 1)
, ('2017-05-11 03:48:05.0600000', NULL, #base_payment, 0);
INSERT INTO dbo.lease_applications_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, APPLICATION_STATUS_CODE
)
SELECT #lease_application
, l.change_date
, l.application_status_code
FROM #la AS l
WHERE l.is_laal = 1;
INSERT INTO dbo.lease_financing_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, BASE_PAYMENT
)
SELECT #lease_application
, l.change_date
, l.base_amount
FROM #la AS l
WHERE l.is_laal = 0;
SELECT #actual = post_approval_payment_amount
FROM [dbo].[post_approval_payment_amount](#lease_application);
IF (#expected <> #actual) SELECT 'Test 2 failed'
ELSE SELECT 'Test 2 passed';
SELECT #lease_application = '38768578'
, #base_payment = 453.70
, #expected = NULL
, #actual = NULL;
DELETE FROM #la;
INSERT INTO #la ( change_date
, application_status_code
, base_amount
, is_laal
)
VALUES ('2017-05-11 03:46:26.4800000', 'L', NULL, 1)
, ('2017-06-09 12:00:36.2000000', 'X', NULL, 1)
, ('2017-06-12 03:48:05.0600000', NULL, #base_payment, 0);
INSERT INTO dbo.lease_applications_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, APPLICATION_STATUS_CODE
)
SELECT #lease_application
, l.change_date
, l.application_status_code
FROM #la AS l
WHERE l.is_laal = 1;
INSERT INTO dbo.lease_financing_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, BASE_PAYMENT
)
SELECT #lease_application
, l.change_date
, l.base_amount
FROM #la AS l
WHERE l.is_laal = 0;
SELECT #actual = post_approval_payment_amount
FROM [dbo].[post_approval_payment_amount](#lease_application);
IF (#actual IS NOT NULL) SELECT 'Test 3 failed'
ELSE SELECT 'Test 3 passed';
SELECT #lease_application = '38282661'
, #base_payment = 451.25
, #expected = 451.25;
DELETE FROM #la;
INSERT INTO #la ( change_date
, application_status_code
, base_amount
, is_laal
)
VALUES ('2017-05-11 03:46:26.4800000', 'O', NULL, 1)
, ('2017-05-11 03:48:05.0600000', NULL, #base_payment, 0)
, ('2017-07-05 10:52:14.6800000', 'O', NULL, 1)
, ('2017-07-05 11:10:24.0400000', 'E', NULL, 1)
, ('2017-07-05 11:10:25.6000000', 'E', NULL, 1)
, ('2017-07-05 11:10:49.1900000', 'L', NULL, 1)
, ('2017-07-06 00:04:30.6400000', 'O', NULL, 1);
INSERT INTO dbo.lease_applications_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, APPLICATION_STATUS_CODE
)
SELECT #lease_application
, l.change_date
, l.application_status_code
FROM #la AS l
WHERE l.is_laal = 1;
INSERT INTO dbo.lease_financing_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, BASE_PAYMENT
)
SELECT #lease_application
, l.change_date
, l.base_amount
FROM #la AS l
WHERE l.is_laal = 0;
SELECT #actual = post_approval_payment_amount
FROM [dbo].[post_approval_payment_amount](#lease_application);
IF (#expected <> #actual) SELECT 'Test 4 failed'
ELSE SELECT 'Test 4 passed';
SELECT #lease_application = '38768578'
, #base_payment = 453.70
, #expected = 453.70;
DELETE FROM #la;
INSERT INTO #la ( change_date
, application_status_code
, base_amount
, is_laal
)
VALUES ('2017-05-11 03:46:26.4800000', 'L', NULL, 1)
, ('2017-05-11 03:48:05.0600000', NULL, 200, 0)
, ('2017-05-12 03:48:05.0600000', NULL, #base_payment, 0)
, ('2017-06-09 12:00:36.2000000', 'X', NULL, 1)
, ('2017-09-18 11:57:13.5100000', NULL, 100, 0);
INSERT INTO dbo.lease_applications_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, APPLICATION_STATUS_CODE
)
SELECT #lease_application
, l.change_date
, l.application_status_code
FROM #la AS l
WHERE l.is_laal = 1;
INSERT INTO dbo.lease_financing_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, BASE_PAYMENT
)
SELECT #lease_application
, l.change_date
, l.base_amount
FROM #la AS l
WHERE l.is_laal = 0;
SELECT #actual = post_approval_payment_amount
FROM [dbo].[post_approval_payment_amount](#lease_application);
IF (#expected <> #actual) SELECT 'Test 5 failed'
ELSE SELECT 'Test 5 passed';
SELECT #lease_application = '38768578'
, #base_payment = 453.70
, #expected = 453.70;
DELETE FROM #la;
INSERT INTO #la ( change_date
, application_status_code
, base_amount
, is_laal
)
VALUES ('2017-05-11 03:46:26.4800000', 'L', NULL, 1)
, ('2017-05-11 03:48:05.0600000', NULL, #base_payment, 0)
, ('2017-06-09 12:00:36.2000000', 'X', NULL, 1)
, ('2017-09-18 11:57:13.5100000', NULL, 100, 0);
INSERT INTO dbo.lease_applications_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, APPLICATION_STATUS_CODE
)
SELECT #lease_application
, l.change_date
, l.application_status_code
FROM #la AS l
WHERE l.is_laal = 1;
INSERT INTO dbo.lease_financing_audit_log ( LEASE_APPLICATION
, CHANGED_DATE
, BASE_PAYMENT
)
SELECT #lease_application
, l.change_date
, l.base_amount
FROM #la AS l
WHERE l.is_laal = 0;
SELECT #actual = post_approval_payment_amount
FROM [dbo].[post_approval_payment_amount](#lease_application);
IF (#expected <> #actual) SELECT 'Test 6 failed'
ELSE SELECT 'Test 6 passed';
DROP TABLE [dbo].[LEASE_APPLICATIONS_AUDIT_LOG];
GO
DROP TABLE [dbo].[LEASE_FINANCING_AUDIT_LOG];
GO
DROP FUNCTION [dbo].[post_approval_payment_amount];
GO
You asked for some thoughts about alternative approaches. You could use these ideas individually or in combination:
Remember that JOINs may be done using an operator other than the equal sign, so you could for example join your tables ON LEASE_APPLICATIONS_AUDIT_LOG.CHANGED_DATE <= LEASE_FINANCING_AUDIT_LOG.CHANGED_DATE.
The LAG and LEAD functions are highly optimal functions for retrieving "nearby" records. The third parameter even allows you to specify the value that will be returned in the event a record is not found - a convenient place to insert your CAST('9999-12-31 23:59:59' AS DATETIME default.
Never underestimate the clarity and performance that can be achieved by the proper use of Common Table Expressions (using the WITH clause).
I have a table that get updated every weeknight.
Someone then pull the table down, assigns values where the QueueT is null based on the number already assigned out and the type.
Think of it as a queueing system to even out workflow as evenly as possible.
Im stuck on attempting to automate the assignment piece
http://sqlfiddle.com/#!3/6a657/1
shows how much is assigned to each person, but how would i got about updating the table to assign each person based on type and even the assignments out as much as possible?
-- create temp table code if needed
create table #tempqueue
(
QueueT varchar(20)
,Type varchar(20)
)
insert into #tempqueue
(
QueueT
,Type
)
values
( 'bob' , 'type1'),
( 'bob' , 'type1'),
( 'john' , 'type2'),
( 'john' , 'type2'),
( 'john' , 'type2'),
( 'null' , 'type1'),
( 'null' , 'type1'),
( 'null' , 'type1'),
( 'null' , 'type1'),
( 'null' , 'type2'),
( 'null' , 'type2'),
( 'tim' , 'type1'),
( 'bob' , 'type1'),
( 'jill' , 'type2'),
( 'jack' , 'type2'),
( 'john' , 'type2'),
( 'null' , 'type1'),
( 'null' , 'type1'),
( 'null' , 'type1'),
( 'null' , 'type1'),
( 'null' , 'type2'),
( 'null' , 'type2'),
( 'null' , 'type2')
select
QueueT
,type
,count(Type) counttype
from #tempqueue
group by
QueueT
,type
First, you need a unique id for the table so each record can be updated individually:
create table tempqueue
(
id int identity(1,1)
,QueueT varchar(20)
,Type varchar(20)
)
Then you can update it using a couple sub queries, min, count, and the row_number windowed function:
create table tempqueue
(
id int identity(1,1)
,QueueT varchar(20)
,Type varchar(20)
)
insert into tempqueue
(
QueueT
,Type
)
values
( 'bob' , 'type1'),
( 'bob' , 'type1'),
( 'john' , 'type2'),
( 'john' , 'type2'),
( 'john' , 'type2'),
( null , 'type1'),
( null , 'type1'),
( null , 'type3'),
( null , 'type1'),
( null , 'type2'),
( null , 'type2'),
( 'tim' , 'type1'),
( 'bob' , 'type1'),
( 'jill' , 'type2'),
( 'jack' , 'type2'),
( 'john' , 'type2'),
( null , 'type1'),
( null , 'type1'),
( null , 'type1'),
( null , 'type1'),
( null , 'type2'),
( null , 'type2'),
( null , 'type2')
-- loop through records until no records are updated
declare #rows_updated int = 1
while #rows_updated > 0
begin
update t
set t.QueueT = u.QueueT
from tempqueue t
-- get min record id per type where QueueT is null
inner join (select Type,min(id) id
from tempqueue
where QueueT is null
group by Type) id
on id.Type = t.Type
and id.id = t.id
-- get QueueT for each Type with the least count
inner join (select QueueT,Type,
row_number() over(partition by Type order by cnt) lst
from (select QueueT,Type,count(*) cnt
from tempqueue
where QueueT is not null
group by QueueT,Type)c)u
on u.Type = id.Type
and u.lst = 1
set #rows_updated = ##rowcount
end
select QueueT,Type,count(*) cnt
from tempqueue
group by QueueT,Type
SQL FIDDLE
Table LPTitle:
CREATE TABLE LPTitle(
title VARCHAR(30) NOT NULL, /* Position title */
CONSTRAINT LPTitle_pkey PRIMARY KEY ( title ) );
INSERT INTO LPTitle VALUES( 'ASSISTANT' );
INSERT INTO LPTitle VALUES( 'ASSOC. LECTURER' );
INSERT INTO LPTitle VALUES( 'LECTURER' );
INSERT INTO LPTitle VALUES( 'SENIOR LECTURER' );
INSERT INTO LPTitle VALUES( 'ASSOC. PROFESSOR' );
INSERT INTO LPTitle VALUES( 'PROFESSOR' );
Table Position:
CREATE TABLE Position(
p# NUMBER(8) NOT NULL, /* Position number */
ptitle VARCHAR(30) NOT NULL, /* Position title */
employer VARCHAR(100) NOT NULL, /* Institution name */
salary NUMBER(9,2) NOT NULL, /* Salary */
extras VARCHAR(50) , /* Extras */
specification LONG , /* Specification */
CONSTRAINT Position_pkey PRIMARY KEY ( p# ),
CONSTRAINT Position_fkey1 FOREIGN KEY ( ptitle )
REFERENCES LPTitle ( title ) );
INSERT INTO Position VALUES ( 00000001, 'LECTURER', 'UNSW', 45000.00, 'computer', 'Teaching');
INSERT INTO Position VALUES ( 00000002, 'LECTURER', 'UOW', 450000.00, 'mouse pad', 'Research');
INSERT INTO Position VALUES ( 00000003, 'SENIOR LECTURER', 'UTS', 50000.00, NULL, 'A lot of hard work' );
INSERT INTO Position VALUES ( 00000004, 'ASSOC. PROFESSOR', 'UOW', 60000.00, NULL, NULL);
INSERT INTO Position VALUES ( 00000005, 'PROFESSOR', 'UQ', 80000.00, 'chair', 'Research' );
INSERT INTO Position VALUES ( 00000006, 'PROFESSOR', 'UNSW', 80000.00, 'chair', 'Research' );
INSERT INTO Position VALUES ( 00000007, 'PROFESSOR', 'UOW', 80000.00, 'chair', 'Teaching and research');
Table Applies:
CREATE TABLE Applies(
a# NUMBER(6) NOT NULL, /* Applicant number */
p# NUMBER(8) NOT NULL, /* Position number */
appdate DATE NOT NULL, /* Application date */
CONSTRAINT Applies_pkey PRIMARY KEY ( a#, p# ),
CONSTRAINT Applies_fkey1 FOREIGN KEY ( a# )
REFERENCES Applicant ( a# )
ON DELETE CASCADE,
CONSTRAINT Applies_fkey2 FOREIGN KEY ( p# )
REFERENCES Position ( p# )
ON DELETE CASCADE);
INSERT INTO Applies VALUES( 000001, 00000001, TO_DATE('13-DEC-1999','DD-MON-YYYY') );
INSERT INTO Applies VALUES( 000002, 00000001, TO_DATE('13-DEC-1999','DD-MON-YYYY') );
INSERT INTO Applies VALUES( 000003, 00000002, TO_DATE('14-NOV-1999','DD-MON-YYYY') );
INSERT INTO Applies VALUES( 000004, 00000002, TO_DATE('20-JAN-2000','DD-MON-YYYY') );
INSERT INTO Applies VALUES( 000005, 00000002, TO_DATE('22-JAN-2000','DD-MON-YYYY') );
INSERT INTO Applies VALUES( 000005, 00000003, TO_DATE('09-MAY-1999','DD-MON-YYYY') );
INSERT INTO Applies VALUES( 000006, 00000003, TO_DATE('17-JUN-1999','DD-MON-YYYY') );
INSERT INTO Applies VALUES( 000007, 00000003, TO_DATE('18-JUN-1999','DD-MON-YYYY') );
INSERT INTO Applies VALUES( 000007, 00000004, TO_DATE('13-APR-2000','DD-MON-YYYY') );
INSERT INTO Applies VALUES( 000008, 00000004, TO_DATE('13-APR-2000','DD-MON-YYYY') );
INSERT INTO Applies VALUES( 000009, 00000004, TO_DATE('14-APR-2000','DD-MON-YYYY') );
INSERT INTO Applies VALUES( 000010, 00000005, TO_DATE('23-SEP-1999','DD-MON-YYYY') );
INSERT INTO Applies VALUES( 000001, 00000006, TO_DATE('26-OCT-1999','DD-MON-YYYY') );
INSERT INTO Applies VALUES( 000002, 00000006, TO_DATE('27-OCT-1999','DD-MON-YYYY') );
INSERT INTO Applies VALUES( 000003, 00000006, TO_DATE('28-OCT-1999','DD-MON-YYYY') );
INSERT INTO Applies VALUES( 000004, 00000007, TO_DATE('01-JAN-2000','DD-MON-YYYY') );
INSERT INTO Applies VALUES( 000005, 00000007, TO_DATE('03-JAN-2000','DD-MON-YYYY') );
INSERT INTO Applies VALUES( 000006, 00000007, TO_DATE('04-JAN-2000','DD-MON-YYYY') );
INSERT INTO Applies VALUES( 000007, 00000007, TO_DATE('07-JAN-2000','DD-MON-YYYY') );
With the 3 tables above, I want to find the titles of all positions that have no applications. How to implements this by using SELECT statements with one or more NOT EXISTS clauses?
This is the query I have so far, the result is always "no rows selected" (which is wrong):
SELECT
LPTitle.title
FROM
LPTitle
FULL OUTER JOIN
Position
ON
LPTitle.title = Position.ptitle
WHERE
NOT EXISTS
(
SELECT Applies.p# FROM Applies INNER JOIN Position ON Applies.p# = Position.p#
)
;
I think the query below will do the job. Please note that you don't need the LPTitle table, as you already have all title values stored in Position tables ptitle column.
Basicly the result is the same: you have an application for all of your 7 positions!
SELECT
p.ptitle
FROM
Position p
WHERE
NOT EXISTS
(
SELECT 1 FROM Applies WHERE p# = p.p#
)
;
If you meant to look for all unused titles, than that's another task:
SELECT
l.title
FROM
LPTitle l
WHERE
NOT EXISTS
(
SELECT 1 FROM Position ptitle = l.title
)
;
I need your help on making on recursive query using a CTE in SQL Server.
I have order no as input parameter.. I need to display its top parent despatch details. even if I search for its children.. ie if I search for order no 3 I should get its top parent order no. that is 20.
Here is my table structure..
CREATE TABLE #TblSerialNo
(
[SRno] [char](20) NOT NULL ,
[CustSrNo] [varchar](75) NULL
)
CREATE TABLE #TblSerialReleation
(
[SRno] [char](20) NOT NULL ,
[ChildSRno] [char](20) NOT NULL
)
CREATE TABLE #TblDespatch
(
[SRno] [char](20) NOT NULL ,
OrderNo INT NOT NULL
)
INSERT INTO #TblSerialNo VALUES ( 'TS1', 'DD123CV1' )
INSERT INTO #TblSerialNo VALUES ( 'TS2', 'DD123CV2' )
INSERT INTO #TblSerialNo VALUES ( 'TS3', 'DD123CV3' )
INSERT INTO #TblSerialNo VALUES ( 'BS1', 'DD12sfs3CV1' )
INSERT INTO #TblSerialNo VALUES ( 'BS2', 'DD1et23CV2' )
INSERT INTO #TblSerialNo VALUES ( 'CS1', 'DD12e3CV1' )
INSERT INTO #TblSerialNo VALUES ( 'CS2', 'DD12fe3CV2' )
INSERT INTO #TblSerialNo VALUES ( 'BS1aa', 'DD12d3CV1' )
INSERT INTO #TblSerialNo VALUES ( 'BS1ab', 'DDd123CV2' )
INSERT INTO #TblSerialNo VALUES ( 'BS1ac', 'DD1r23CV3' )
INSERT INTO #TblSerialNo VALUES ( 'BS2aa', 'DDs123CV4' )
INSERT INTO #TblSerialNo VALUES ( 'BS2ab', 'DD12d3CV1' )
INSERT INTO #TblSerialNo VALUES ( 'BS2ac', 'DD1s23CV2' )
INSERT INTO #TblSerialNo VALUES ( 'CS1aa', 'DD1s23CV3' )
INSERT INTO #TblSerialNo VALUES ( 'CS1ab', 'DD12s3CV4' )
INSERT INTO #TblSerialNo VALUES ( 'CS1ac', 'DD123dCV1' )
INSERT INTO #TblSerialNo VALUES ( 'CS2aa', 'DDa123CV2' )
INSERT INTO #TblSerialNo VALUES ( 'CS2ab', 'DDa123CV3' )
INSERT INTO #TblSerialNo VALUES ( 'CS2ac', 'DDa123CV4' )
--================ Relation table ==============
INSERT INTO #TblSerialReleation VALUES ( 'TS1', 'BS1' )
INSERT INTO #TblSerialReleation VALUES ( 'TS1', 'BS2' )
INSERT INTO #TblSerialReleation VALUES ( 'TS2', 'CS1' )
INSERT INTO #TblSerialReleation VALUES ( 'TS2', 'CS2' )
INSERT INTO #TblSerialReleation VALUES ( 'BS1', 'BS1aa' )
INSERT INTO #TblSerialReleation VALUES ( 'BS1', 'BS1ab' )
INSERT INTO #TblSerialReleation VALUES ( 'BS1', 'BS1ac' )
INSERT INTO #TblSerialReleation VALUES ( 'BS2', 'BS2aa' )
INSERT INTO #TblSerialReleation VALUES ( 'BS2', 'BS2ab' )
INSERT INTO #TblSerialReleation VALUES ( 'BS2', 'BS2ac' )
INSERT INTO #TblSerialReleation VALUES ( 'CS1', 'CS1aa' )
INSERT INTO #TblSerialReleation VALUES ( 'CS1', 'CS1ab' )
INSERT INTO #TblSerialReleation VALUES ( 'CS1', 'CS1ac' )
INSERT INTO #TblSerialReleation VALUES ( 'CS2', 'CS2aa' )
INSERT INTO #TblSerialReleation VALUES ( 'CS2', 'CS2ab' )
INSERT INTO #TblSerialReleation VALUES ( 'CS2', 'CS2ac' )
--=========== Despatch
INSERT INTO #TblDespatch VALUES ( 'CS2ac', 1 )
INSERT INTO #TblDespatch VALUES ( 'CS2ab', 1 )
INSERT INTO #TblDespatch VALUES ( 'CS2ac', 1 )
INSERT INTO #TblDespatch VALUES ( 'CS1aa', 1 )
INSERT INTO #TblDespatch VALUES ( 'CS1ac', 1 )
INSERT INTO #TblDespatch VALUES ( 'CS2ac', 1 )
INSERT INTO #TblDespatch VALUES ( 'CS2ac', 1 )
INSERT INTO #TblDespatch VALUES ( 'TS1', 1 )
INSERT INTO #TblDespatch VALUES ( 'TS3', 2 )
INSERT INTO #TblDespatch VALUES ( 'TS2', 3 )
INSERT INTO #TblDespatch VALUES ( 'BS2ab', 20 )
DROP TABLE #TblDespatch
DROP TABLE #TblSerialNo
DROP TABLE #TblSerialReleation
Thanks in advance.
Looking at your data, the relation seems to go the other way around (BS2ab (Order 20) is the child of TS1(Order 3) through BS2.
If this is the case, starting from the child (BS2ab) you can find its top parent with the following statement:
;with ParentOrders as(
select
convert(char(20), 'BS2ab')as SRno,
0 as Level
union all
select r.SRno, o.Level + 1
from ParentOrders o
join TblSerialReleation r
on o.SRNo = r.ChildSRno
)
select top 1 SRNO
from ParentOrders
order by Level desc
Here's a working sample of the query: http://www.sqlfiddle.com/#!3/e253e/6