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
Related
I have the following table format:
CREATE TABLE tmp_tbl
(
gcode_id int,
g1code varchar(20),
g2code varchar(20),
g3code varchar(20),
g4code varchar(20)
);
And the following values are inserted:
insert into tmp_tbl values (1, 'AFR', 'AFR-EAST', 'BI', 'BIBJM');
insert into tmp_tbl values (2, 'AFR', 'AFR-SOUTH', 'ZA', 'ZACPT');
insert into tmp_tbl values (3, 'EUR', 'EUR-BRI_IS', 'GB', 'GBMAN');
insert into tmp_tbl values (4, 'EUR', 'EUR-WEST', 'NL', 'NLZWO');
insert into tmp_tbl values (5, 'EUR', 'EUR-WEST', 'BE', 'BELEB');
insert into tmp_tbl values (6, 'EUR', 'EUR-WEST', 'BE', '');
insert into tmp_tbl values (7, 'EUR', 'EUR-WEST', 'NL', '');
insert into tmp_tbl values (8, 'EUR', 'EUR-WEST', '', '');
This is a list of codes where g1code = continent, g2code = region, g3code = country, g4code = city.
The rows with columns that have empty values are to be included if the rest matches.
So if I for example select row 4 then also want row 7 and row 8 to be included. As the empty values can match anything.
I created the following query for this:
SELECT DISTINCT
t1.*,
t2.*,
t3.*,
t4.*
FROM
tmp_tbl tm,
(SELECT * FROM tmp_tbl WHERE g4code = 'NLZWO') g4
OUTER APPLY
(SELECT * FROM tmp_tbl t
WHERE t.g1code = g4.g1code AND t.g2code = '' AND t.g3code = '' AND t.g4code = '') t1
OUTER APPLY
(SELECT * FROM tmp_tbl t
WHERE t.g1code = g4.g1code AND t.g2code = g4.g2code AND t.g3code = '' AND t.g4code = '') t2
OUTER APPLY
(SELECT * FROM tmp_tbl t
WHERE t.g1code = g4.g1code AND t.g2code = g4.g2code AND t.g3code = g4.g3code AND t.g4code = '') t3
OUTER APPLY
(SELECT * FROM tmp_tbl t
WHERE t.g1code = g4.g1code AND t.g2code = g4.g2code AND t.g3code = g4.g3code AND t.g4code = g4.g4code) t4
This does work but I only get 1 row and everything in columns like this:
gcode_id g1code g2code g3code g4code gcode_id g1code g2code g3code g4code gcode_id g1code g2code g3code g4code gcode_id g1code g2code g3code g4code
NULL NULL NULL NULL NULL 8 EUR EUR-WEST 7 EUR EUR-WEST NL 4 EUR EUR-WEST NL NLZWO
Is there a way to do this more efficiently or convert the columns to rows and then end up eventually with id 8, 7 and 4 (where the nulls are filtered out as they are not relevant)?
Thanks
Are you looking for or?
select t.*
from tmp_tbl t join
tmp_tbl t2
on (t.g1code = t2.g1code or t.g1code = '') and
(t.g2code = t2.g2code or t.g2code = '') and
(t.g3code = t2.g3code or t.g3code = '')
where t2.g4code = 'NLZWO';
Here is a db<>fiddle.
Maybe could be more elegant and generic, but this works.
create table #tmp_tbl (
gcode_id int,
g1code varchar(20),
g2code varchar(20),
g3code varchar(20),
g4code varchar(20)
);
insert into #tmp_tbl values (1, 'AFR', 'AFR-EAST', 'BI', 'BIBJM');
insert into #tmp_tbl values (2, 'AFR', 'AFR-SOUTH', 'ZA', 'ZACPT');
insert into #tmp_tbl values (3, 'EUR', 'EUR-BRI_IS', 'GB', 'GBMAN');
insert into #tmp_tbl values (4, 'EUR', 'EUR-WEST', 'NL', 'NLZWO');
insert into #tmp_tbl values (5, 'EUR', 'EUR-WEST', 'BE', 'BELEB');
insert into #tmp_tbl values (6, 'EUR', 'EUR-WEST', 'BE', '');
insert into #tmp_tbl values (7, 'EUR', 'EUR-WEST', 'NL', '');
insert into #tmp_tbl values (8, 'EUR', 'EUR-WEST', '', '');
insert into #tmp_tbl values (9, 'EUR', '', '', '');
;
with main as (
select *
from #tmp_tbl
where g4code = 'NLZWO'
),
parent as (
select m.gcode_id
, m.g1code
, m.g2code
, m.g3code
, m.g4code
from main m
union
select p.gcode_id
, p.g1code
, p.g2code
, p.g3code
, p.g4code
from #tmp_tbl p
inner join main m on m.g3code = p.g3code
and m.g2code = p.g2code
and m.g1code = p.g1code
and p.g4code = ''
),
grandparent as (
select p.gcode_id
, p.g1code
, p.g2code
, p.g3code
, p.g4code
from parent p
union
select gp.gcode_id
, gp.g1code
, gp.g2code
, gp.g3code
, gp.g4code
from #tmp_tbl gp
inner join parent p on p.g2code = gp.g2code
and p.g1code = gp.g1code
and gp.g3code = ''
),
greatgrandparent as (
select gp.gcode_id
, gp.g1code
, gp.g2code
, gp.g3code
, gp.g4code
from grandparent gp
union
select ggp.gcode_id
, ggp.g1code
, ggp.g2code
, ggp.g3code
, ggp.g4code
from #tmp_tbl ggp
inner join grandparent gp on gp.g1code = ggp.g1code
and ggp.g2code = ''
)
select *
from greatgrandparent
Or were you really looking for it to all be on one line?
select *
from #tmp_tbl m
inner join #tmp_tbl p on p.g3code = m.g3code
and p.g2code = m.g2code
and p.g1code = m.g1code
and p.g4code = ''
inner join #tmp_tbl gp on gp.g2code = p.g2code
and gp.g1code = p.g1code
and gp.g3code = ''
inner join #tmp_tbl ggp on ggp.g1code = gp.g1code
and ggp.g2code = ''
where m.g4code = 'NLZWO'
This is my input table
create table #table1 (id int, FN varchar(20), startdate varchar(20), id1 varchar)
insert #table1
select 1, 'Joe', '2019-01-01', 'A'
union select 1, 'Joe', '2019-01-01', 'B'
union select 1, 'Joe', '2019-01-05', 'C'
union select 1, 'Joe', '2019-01-05', 'D'
union select 1, 'Joe', '2019-01-06', 'E'
union select 2, 'john', '2019-01-05', 'F'
union select 2, 'john', '2019-01-06', 'G'
union select 2, 'john', '2019-01-06', 'H'
union select 2, 'john', '2019-01-07', 'I'
I tried the following code
select *
, dense_rank() OVER (partition by id, fn order by startdate)
, lead(startdate,1) OVER (partition by id, fn order by startdate)
from #table1
order by id
But I require the following output:
I know that there might be a better approach but a least this is a working solution:
select *,
(select MIN(startdate)
from #table1 t1
where t1.id = #table1.id and
t1.fn = #table1.fn and
t1.startdate > #table1.startdate) enddate
from #table1
Result
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 currently have 2 SQL tables that look like this:
and...
I need to write a SELECT statement that retrieves all products from the DataTable that contain rows that match the FilterTable.
So based on my example tables above, if I were to run the query, it would return the following result:
I recently found a question that kind of attempts this:
SQL query where ALL records in a join match a condition?
but have been unsuccessful in implementing something similar
Note - I am using Microsoft SQL Server 2008
This is a little complicated, but here is one solution. Basically you need to check to see how many records from the datatable match all the records from the filtertable. This uses a subquery to do that:
SELECT *
FROM DataTable
WHERE ID IN (
SELECT DT.ID
FROM DataTable DT
JOIN FilterTable FT ON FT.Name = DT.Name
AND FT.Value = DT.VALUE
GROUP BY DT.ID
HAVING COUNT(*) = (SELECT COUNT(*) FROM FilterTable)
)
SQL Fiddle Demo
This will work:
SELECT * FROM Data WHERE ID NOT IN (
SELECT ID FROM Data JOIN Filter
on Data.Name = Filter.Name and Data.Value <> Filter.Value
)
I set up a SQL Fiddle if you want to try other things:
http://sqlfiddle.com/#!3/38b87/6
EDIT:
Better answer:
SELECT *
FROM DATA
WHERE ID NOT IN (
SELECT ID
FROM DATA
JOIN Filter ON DATA.Name = Filter.Name
AND DATA.Value <> Filter.Value
) AND ID IN
(
SELECT ID
FROM DATA
JOIN Filter ON DATA.Name = Filter.Name
)
This now fits where there is at least one filter that matches, and none that don't.
In case you can use sp_executesql (you are using procedure).
SET NOCOUNT ON
GO
CREATE TABLE Data
(
[ID] INT
,[Name] VARCHAR(12)
,[Value] VARCHAR(2)
)
CREATE TABLE Filter
(
[Name] VARCHAR(12)
,[Value] VARCHAR(2)
)
INSERT INTO Data ([ID], [Name], [Value])
VALUES (1, 'productname', 'A')
,(1, 'cost', '20')
,(1, 'active', 'Y')
,(2, 'productname', 'A')
,(2, 'cost', '20')
,(2, 'active', 'N')
,(3, 'productname', 'B')
,(3, 'cost', '20')
,(3, 'active', 'Y')
,(4, 'productname', 'A')
,(4, 'cost', '20')
,(4, 'active', 'Y')
INSERT INTO Filter ([Name], [Value])
VALUES ('productname', 'A')
,('active', 'Y')
DECLARE #SQLColumns NVARCHAR(MAX) = SUBSTRING((SELECT DISTINCT ',[' +[Name] +']' FROM Data FOR XML PATH('')),2,4000)
DECLARE #SQLFilterColumns NVARCHAR(MAX) = SUBSTRING((SELECT 'AND [' +[Name] +'] = ''' + [Value] + ''' ' FROM Filter FOR XML PATH('')),4,4000)
DECLARE #SQLStatement NVARCHAR(MAX) = N'
;WITH DataSource ([ID]) AS
(
SELECT [ID]
FROM
(
SELECT [ID]
,[Name]
,[Value]
FROM Data
) DataSource
PIVOT
(
MAX([Value]) FOR [Name] IN (' + #SQLColumns+ ')
) PVT
WHERE ' + #SQLFilterColumns + '
)
SELECT DT.[ID]
,DT.[Name]
,DT.[Value]
FROM Data DT
INNER JOIN DataSource DS
ON DT.[ID] = DS.[ID]
'
EXECUTE sp_executesql #SQLStatement
DROP TABLE Data
DROP TABLE Filter
SET NOCOUNT OFF
GO
Here is an option using a couple of PIVOTs
DECLARE #Data table ([ID] INT, [Name] VARCHAR(12), [Value] VARCHAR(2) )
DECLARE #Filter TABLE ( [Name] VARCHAR(12), [Value] VARCHAR(2) )
INSERT INTO #Data ([ID], [Name], [Value])
VALUES (1, 'productname', 'A')
,(1, 'cost', '20')
,(1, 'active', 'Y')
,(2, 'productname', 'A')
,(2, 'cost', '20')
,(2, 'active', 'N')
,(3, 'productname', 'B')
,(3, 'cost', '20')
,(3, 'active', 'Y')
,(4, 'productname', 'A')
,(4, 'cost', '20')
,(4, 'active', 'Y')
INSERT INTO #Filter ([Name], [Value])
VALUES ('productname', 'A')
,('active', 'Y');
SELECT *
FROM ( SELECT *
FROM (select [ID], [Name], [value] from #Data) as s
PIVOT
( MAX([value]) FOR [name] in ( [productname], [active])
) as pvt) B
INNER JOIN
( SELECT *
FROM (select [name], [value] from #Filter) as f
PIVOT
( MAX([value]) for [Name] IN ([productname], [active])
) AS fpvt
) F
ON F.active = b.active and f.productname = b.productname
By doing a PIVOT on the DATA table and then on the FILTER table, it allows them to be lined up for an inner join. This returns the records that match within both,
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.