Number of records created per day - sql

In my PostgreSQL database I have the following schema:
CREATE TABLE programs (
id integer,
description text
);
CREATE TABLE public.messages (
id integer,
program_id integer,
text text,
message_template_id integer
);
CREATE TABLE public.message_templates (
id integer,
deliver_day integer
);
INSERT INTO programs VALUES(1, 'Test program');
INSERT INTO messages VALUES(1,1, 'Test message 1', 1);
INSERT INTO message_templates VALUES(1, 1);
INSERT INTO messages VALUES(2,1, 'Test message 2', 2);
INSERT INTO message_templates VALUES(2, 3);
INSERT INTO messages VALUES(3,1, 'Test message 3', 3);
INSERT INTO message_templates VALUES(3, 5);
Now I want to get number of message sent per day throughout the life of the program, query result should look like this:
day count
--------|----------
1 1
2 0
3 1
4 0
5 1
Is there any way of doing that in PostgreSQL?
https://www.db-fiddle.com/f/gvxijmp8u6wr6mYcSoAeVV/2

I decided to use generate_series:
SELECT d AS "Day", count(mt.id) FROM generate_series(
(SELECT min(delivery_day) from message_templates),
(SELECT max(delivery_day) from message_templates)
) d
left join message_templates mt on mt.delivery_day = d
group by d.d
Query is working fine. Maybe there is better way of doing this?

You could use this:
WITH tmp AS
(
SELECT m.program_id, a.n AS d
FROM generate_series(1,
(SELECT MAX(deliver_day) FROM message_templates)
) AS a(n)
CROSS JOIN
(
SELECT DISTINCT program_id
FROM messages
) m
)
SELECT t.program_id,
t.d AS "day",
COUNT(m.program_id) AS "count" -- COUNT(m.id)
FROM tmp t
LEFT JOIN message_templates mt
ON t.d = mt.deliver_day
LEFT JOIN messages m
ON m.message_template_id = mt.id AND t.program_id = m.program_id
GROUP BY t.program_id, t.d
ORDER BY t.program_id, t.d;
Tested in db-fiddle

Related

Calcul (multiplication) of two select-result

I'm trying to multiply two numbers I got from a SELECT statement of a unique query. I want to get the number of providers and the number of proposals (the query I made displays that), and multiply both on the same line (that I can't do).
I've made a very simple example to show you (same code as below) : DEMO ON FIDDLE
Create 2 providers working on 2 departments :
CREATE TABLE ##Provider
(
id INT,
p_name VARCHAR(50),
id_dep INT
)
INSERT INTO ##Provider (id, p_name, id_dep) VALUES
(1, 'toto', 10),
(2, 'toto', 11),
(3, 'tata', 9);
Create 4 proposal on 2 departments :
CREATE TABLE ##Proposal
(
id INT,
c_name VARCHAR(50),
id_dep INT
)
INSERT INTO ##Proposal (id, c_name, id_dep) VALUES
(1, 'propA', 10),
(2, 'propB', 09),
(3, 'propC', 10),
(4, 'propD', 10);
Create the department table :
CREATE TABLE ##Department
(
id INT,
d_name VARCHAR(50)
)
INSERT INTO ##Department (id, d_name) VALUES
(9, 'dep9')
,(10, 'dep10')
,(11, 'dep11');
Here I can display the number of providers and proposals by department (the real query is a lot more complex so I'd like to keep the 2 subrequests) :
select
id,
d_name,
nb_provider = (
SELECT COUNT(DISTINCT Id)
FROM ##Provider p
WHERE p.id_dep = dep.id
),
nb_proposal = (
SELECT COUNT(DISTINCT Id)
FROM ##Proposal pp
WHERE pp.id_dep = dep.id
)
from ##Department dep
WHERE dep.id = 10
But I CAN'T display a calcul of those two number :
select
id,
d_name,
nb_provider = (
SELECT COUNT(DISTINCT Id)
FROM ##Provider p
WHERE p.id_dep = dep.id
),
nb_proposal = (
SELECT COUNT(DISTINCT Id)
FROM ##Proposal pp
WHERE pp.id_dep = dep.id
),
calcul = (nb_provider * nb_proposal) --> DOESN'T WORK
from ##Department dep
WHERE dep.id = 10
I haven't tried a lot because I am not sure if this is even possible... maybe should I use UNION ?
I would recommend lateral joins:
select
d.id,
d.d_name,
p.nb_provider,
pp.nb_proposal
(p.nb_provider * pp.nb_proposal) calcul
from ##department d
outer apply (
select count(distinct id) nb_provider
from ##provider p
where p.id_dep = d.id
) p
outer apply (
select count(distinct id) nb_proposal
from ##proposal pp
where pp.id_dep = d.id
) pp
where d.id = 10

Check for multiple distinct occurrences by group

Input Data
Some_Table
ST_Field1 ST_Field2
Apple A
Apple A
Apple D
Orange D
Orange E
Orange Z
Pear D
Pear G
Pear C
Reference_Table
RT_Field1 RT_Field2
1 A
1 B
1 C
2 D
2 E
2 F
3 G
Expected Result:
ST_Field1 ST_Field2
Orange D
Orange E
CREATE TABLE SOME_TABLE
( ST_Field1 VARCHAR(100),
ST_Field2 VARCHAR(100)
);
INSERT INTO SOME_TABLE VALUES ('Apple','A');
INSERT INTO SOME_TABLE VALUES ('Apple','A');
INSERT INTO SOME_TABLE VALUES ('Apple','D');
INSERT INTO SOME_TABLE VALUES ('Orange','D');
INSERT INTO SOME_TABLE VALUES ('Orange','E');
INSERT INTO SOME_TABLE VALUES ('Orange','Z');
INSERT INTO SOME_TABLE VALUES ('Pear','D');
INSERT INTO SOME_TABLE VALUES ('Pear','G');
INSERT INTO SOME_TABLE VALUES ('Pear','C');
CREATE TABLE REFERENCE_TABLE
( RT_Field1 INTEGER,
RT_Field2 VARCHAR(100)
);
INSERT INTO REFERENCE_TABLE VALUES (1,'A');
INSERT INTO REFERENCE_TABLE VALUES (1,'B');
INSERT INTO REFERENCE_TABLE VALUES (1,'C');
INSERT INTO REFERENCE_TABLE VALUES (2,'D');
INSERT INTO REFERENCE_TABLE VALUES (2,'E');
INSERT INTO REFERENCE_TABLE VALUES (2,'F');
INSERT INTO REFERENCE_TABLE VALUES (3,'G');
It can be assumed that RT_Field2 is unique.
I'm looking to get the records from Some_Table which have multiple distinct values from RT_Field2, group by RT_Field1, by ST_Field1.
So from the reference table {A,B,C} are a grouping. I want to see if for a given ST_Field1 I see either {A,B};{B,c},{A,C}. I don't, I see A and C present, but across Apple and Pear.
The only success is Orange, where I'm looking for {D,E},{D,F}, or {E,F} and find D and E both for Orange.
I have:
WITH DUP_VALUES_RTF2 AS
( SELECT *
FROM (SELECT DST.ST_Field1,
DST.ST_Field2,
COUNT(1) OVER (PARTITION BY RT.RT_Field1) cnt_RTF1
FROM (SELECT DISTINCT
ST_Field1,
ST_Field2
FROM Some_Table
) DST
INNER
JOIN REFERENCE_TABLE RT
ON DST.ST_Field2 = RT.RT_Field2
) TMP
WHERE cnt_RTF1 > 1
)
SELECT *
FROM SOME_TABLE ST
WHERE EXISTS
( SELECT 1
FROM DUP_VALUES_RTF2 DVR
WHERE ST.ST_Field1 = DVR.ST_Field1
AND ST.ST_Field2 = DVR.ST_Field2
);
Which doesn't even really come close because it doesn't handle the grouping at all correctly and is really ugly. Maybe I'm just going brain dead after 5pm.
If I understand this correctly, you want to match on st_field1 and rt_field1, looking for duplicates in rt_field2. You can use window functions for this:
select s.*
from (select s.*, rt.rt_field1, rt.rt_field2,
min(rt.rt_field2) over (partition by s.st_field1, r.rt_field1) as min_rt2,
max(rt.rt_field2) over (partition by s.st_field1, r.rt_field1) as max_rt2
from sometable s join
reference_table r
on s.st_field2 = r.rt_field2
) s
where min_rt2 <> max_rt2;
you can try something like below
; with distinctSet as
(select distinct s.*,RT_Field1 from SOME_TABLE s join REFERENCE_TABLE r on s.ST_Field2=r.RT_Field2
)
,
uniqueSet as
(
select RT_Field1,ST_Field1
from distinctSet
group by RT_Field1,ST_Field1
having count(1)>1
),
resultSet as
(
select
distinct
s.*
from SOME_TABLE s
join REFERENCE_TABLE r
on s.ST_Field2=r.RT_Field2
join uniqueSet u
on u.RT_Field1=r.RT_Field1
and u.ST_Field1=s.ST_Field1
)
select * from resultSet

query to count number of unique relations

I have 3 tables:
t_user (id, name)
t_user_deal (id, user_id, deal_id)
t_deal (id, title)
multiple user can be linked to the same deal. (I'm using oracle but it should be similar, I can adapt it)
How can I get all the users (name) with the number of unique user he made a deal with.
let's explain with some data:
t_user:
id, name
1, joe
2, mike
3, John
t_deal:
id, title
1, deal number 1
2, deal number 2
t_user_deal:
id, user_id, deal_id
1, 1, 1
2, 2, 1
3, 1, 2
4, 3, 2
the result I expect:
user_name, number of unique user he made a deal with
Joe, 2
Mike, 1
John, 1
I've try this but I didn't get the expected result:
SELECT tu.name,
count(tu.id) AS nbRelations
FROM t_user tu
INNER JOIN t_user_deal tud ON tu.id = tud.user_id
INNER JOIN t_deal td ON tud.deal_id = td.id
WHERE
(
td.id IN
(
SELECT DISTINCT td.id
FROM t_user_deal tud2
INNER JOIN t_deal td2 ON tud2.deal_id = td2.id
WHERE tud.id <> tud2.user_id
)
)
GROUP BY tu.id
ORDER BY nbRelations DESC
thanks for your help
This should get you the result
SELECT id1, count(id2),name
FROM (
SELECT distinct tud1.user_id id1 , tud2.user_id id2
FROM t_user_deal tud1, t_user_deal tud2
WHERE tud1.deal_id = tud2.deal_id
and tud1.user_id <> tud2.user_id) as tab, t_user tu
WHERE tu.id = id1
GROUP BY id1,name
Something like
select name, NVL (i.ud, 0) ud from t_user join (
SELECT user_id, count(*) ud from t_user_deal group by user_id) i on on t_user.id = i.user_id
where i.ud > 0
Unless I'm missing somethig here. It actually sounds like your question references having a second user in the t_user_deal table. The model you've described here doesn't include that.
PostgreSQL example:
create table t_user (id int, name varchar(255)) ;
create table t_deal (id int, title varchar(255)) ;
create table t_user_deal (id int, user_id int, deal_id int) ;
insert into t_user values (1, 'joe'), (2, 'mike'), (3, 'john') ;
insert into t_deal values (1, 'deal 1'), (2, 'deal 2') ;
insert into t_user_deal values (1, 1, 1), (2, 2, 1), (3, 1, 2), (4, 3, 2) ;
And the query.....
SELECT
name, COUNT(DISTINCT deal_id)
FROM
t_user INNER JOIN t_user_deal ON (t_user.id = t_user_deal.user_id)
GROUP BY
user_id, name ;
The DISTINCT might not be necessary (in the COUNT(), that is). Depends on how clean your data is (e.g., no duplicate rows!)
Here's the result in PostgreSQL:
name | count
------+-------
joe | 2
mike | 1
john | 1
(3 rows)

Access 97 Outer join issue

I have two tables I want to join.
Table A has one column, named "Week", and contains 52 rows: 1,2,3,4,5,6 etc.
Table 2 has three columns, named "Name", "Week", and "Total", and contains 10 rows:
'Bob', 1, 1
'Bob', 3, 1
'Joe', 4, 1
'Bob', 6, 1
I want to join these together so that my data looks like:
NAME|WEEK|TOTAL
'Bob', 1, 1
'Bob', 2, 0
'Bob', 3, 1
'Bob', 4, 0
'Bob', 5, 0
'Bob', 6, 1
As you can see, a simple outer join. However, when I try to do this, I'm not getting the expected result, no matter what kind of join I use.
My query below:
SELECT a.WEEK, b.Total
FROM Weeks a LEFT JOIN Totals b ON (a.Week = b.Week and b.Name ='Bob')
The result of this query is
NAME|WEEK|TOTAL
'Bob', 1, 1
'Bob', 3, 1
'Bob', 6, 1
Thanks in advance for the help!
I know its access but your join is incorrect. Here we go in sql server..same concept just look at the join condition:
--dont worry about this code im just creating some temp tables
--table to store one column (mainly week number 1,2..52)
CREATE TABLE #Weeks
(
weeknumber int
)
--insert some test data
--week numbers...I'll insert some for you
INSERT INTO #Weeks(weeknumber) VALUES(1)
INSERT INTO #Weeks(weeknumber) VALUES(2)
INSERT INTO #Weeks(weeknumber) VALUES(3)
INSERT INTO #Weeks(weeknumber) VALUES(4)
INSERT INTO #Weeks(weeknumber) VALUES(5)
INSERT INTO #Weeks(weeknumber) VALUES(6)
--create another table with two columns storing the week # and a total for that week
CREATE TABLE #Table2
(
weeknumber int,
total int
)
--insert some data
INSERT INTO #Table2(weeknumber, total) VALUES(1, 100)
--notice i skipped week 2 on purpose to show you the results
INSERT INTO #Table2(weeknumber, total) VALUES(3, 100)
--here's the magic
SELECT t1.weeknumber as weeknumber, ISNULL(t2.total,0) as total FROM
#Weeks t1 LEFT JOIN #Table2 t2 ON t1.weeknumber=t2.weeknumber
--get rid of the temp tables
DROP TABLE #table2
DROP TABLE #Weeks
Results:
1 100
2 0
3 100
4 0
5 0
6 0
Take your week number table (the table that has one column:
SELECT t1.weeknumber as weeknumber
Add to it a null check to replace the null value with a 0. I think there is something in access like ISNULL:
ISNULL(t2.total, 0) as total
And start your join from your first table and left join to your second table on the weeknumber field. The result is simple:
SELECT t1.weeknumber as weeknumber, ISNULL(t2.total,0) as total FROM
#Weeks t1 LEFT JOIN #Table2 t2 ON t1.weeknumber=t2.weeknumber
Do not pay attention to all the other code I have posted, that is only there to create temp tables and insert values into the tables.
SELECT b.Name, b.Week, b.Total
FROM Totals AS b
WHERE b.Name ='Bob'
UNION
SELECT 'Bob' AS Name, a.Week, 0 AS Total
FROM Weeks AS a
WHERE NOT EXISTS ( SELECT *
FROM Totals AS b
WHERE a.Week = b.Week
AND b.Name ='Bob' );
You were on the right track, but just needed to use a left join. Also the NZ function will put a 0 if total is null.
SELECT Totals.Person, Weeks.WeekNo, Nz(Totals.total, 0) as TotalAmount
FROM Weeks LEFT JOIN Totals
ON (Weeks.WeekNo = Totals.weekno and Totals.Person = 'Bob');
EDIT: The query you now have won't even give the results you've shown because you left out the Name field (Which is a bad name for a field because it is a reserved word.). You're still not providing all the information. This query works.
*Another Approach: * Create a separate query on the Totals table having a where clause: Name = 'Bob'
Select Name, WeekNo, Total From Totals Where Name = 'Bob';
and substitute that query for the Totals table in this query.
Select b.Name, w.WeekNo, b.total
from Weeks as w
LEFT JOIN qryJustBob as b
on .WeekNo = b.WeekNo;

Recursive sql problem

I have a problem that I would like have solved via a SQL query. This is going to
be used as a PoC (proof of concept).
The problem:
Product offerings are made up of one or many product instances, a product
instance can belong to many product offerings.
This can be realised like this in a table:
PO | PI
-----
A | 10
A | 11
A | 12
B | 10
B | 11
C | 13
Now I would like to get back the product offer from a set of product instances.
E.g. if we send in 10,11,13 the expected result back is B & C, and if we send in
only 10 then the result should be NULL since no product offering is made up of
only 10. Sending in 10,11,12 would result in A (not A & B since 12 is not a valid product offer in it self).
Prerequisites:
The combination of product instances sent in can only result in one specific
combination of product offerings, so there is only one solution to each query.
Okay, I think I have it. This meets the constraints you provided. There might be a way to simplify this further, but it ate my brain a little:
select distinct PO
from POPI x
where
PO not in (
select PO
from POPI
where PI not in (10,11,12)
)
and PI not in (
select PI
from POPI
where PO != x.PO
and PO not in (
select PO
from POPI
where PI not in (10,11,12)
)
);
This yields only results who fill the given set which are disjoint with all other results, which I think is what you were asking for. For the test examples given:
Providing 10,11,12 yields A
Providing 10,11,13 yields B,C
Edit: Whilst I think mine works fine, Adam's answer is without a doubt more elegant and more efficient - I'll just leave mine here for posterity!
Apologies since I know this has been tagged as an Oracle issue since I started playing. This is some SQL2008 code which I think works for all the stated cases....
declare #test table
(
[PI] int
)
insert #test values (10), (11), (13)
declare #testCount int
select #testCount = COUNT(*) from #test
;with PO_WITH_COUNTS as
(
select PO_FULL.PO, COUNT(PO_FULL.[PI]) PI_Count
from ProductOffering PO_FULL
left
join (
select PO_QUALIFYING.PO, PO_QUALIFYING.[PI]
from ProductOffering PO_QUALIFYING
where PO_QUALIFYING.[PI] in (select [PI] from #test)
) AS QUALIFYING
on QUALIFYING.PO = PO_FULL.PO
and QUALIFYING.[PI] = PO_FULL.[PI]
group by
PO_FULL.PO
having COUNT(PO_FULL.[PI]) = COUNT(QUALIFYING.[PI])
)
select PO_OUTER.PO
from PO_WITH_COUNTS PO_OUTER
cross
join PO_WITH_COUNTS PO_INNER
where PO_OUTER.PI_Count = #testCount
or PO_OUTER.PO <> PO_INNER.PO
group by
PO_OUTER.PO, PO_OUTER.PI_Count
having PO_OUTER.PI_Count = #testCount
or PO_OUTER.PI_Count + SUM(PO_INNER.PI_Count) = #testCount
Not sure if Oracle has CTEs but could just state the inner query as two derived tables. The cross join in the outer query lets us find combinations of offerings that have all the valid items. I know that this will only work based on the statement in the question that the data is such that there is only 1 valid combination for each requested set, Without that it's even more complicated as counts are not enough to remove combinations that have duplicate products in them.
I don't have a db in front of me, but off the top of my head you want the list of POs that don't have any PIs not in your input list, ie
select distinct po
from tbl
where po not in ( select po from tbl where pi not in (10,11,13) )
Edit: Here are the example other cases:
When input PI = 10,11,13 the inner select returns A so the outer select returns B, C
When input PI = 10 the inner select returns A,B,C so the outer select returns no rows
When input PI = 10,11,12 the inner select returns C so the outer select returns A,B
Edit: Adam has pointed out that this last case doesn't meet the requirement of only returning A (that'll teach me for rushing), so this isn't yet working code.
Select Distinct PO
From Table T
-- Next eliminates POs that contain other PIs
Where Not Exists
(Select * From Table
Where PO = T.PO
And PI Not In (10, 11, 12))
-- And this eliminates POs that do not contain all the PIs
And Not Exists
(Select Distinct PI From Table
Where PI In (10, 11, 12)
Except
Select Distinct PI From Table
Where PO = T.PO
or, if your database does not implement EXCEPT...
Select Distinct PO
From Table T
-- Next predicate eliminates POs that contain other PIs
Where Not Exists
(Select * From Table
Where PO = T.PO
And PI Not In (10, 11, 12))
-- And this eliminates POs that do not contain ALL the PIs
And Not Exists
(Select Distinct PI From Table A
Where PI In (10, 11, 12)
And Not Exists
(Select Distinct PI From Table
Where PO = T.PO
And PdI = A.PI))
Is it possible that a customers asks for a product more than once?
For example: he/she asks an offering for 10,10,11,11,12?
If this is possible than solutions like
select ...
from ...
where pi in (10,10,11,11,12)
will not work.
Because 'pi in (10,10,11,11,12)' is the same as 'pi in (10,11,12)'.
A solution for 10,10,11,11,12 is A&B.
well some pseudo code from the top of my head here:
select from table where PI = 10 or pi =11, etc
store the result in a temp table
select distinct PO and count(PI) from temp table.
now for each PO you can get the total available PI offerings. if the number of PIs available matches the count in the temp table, it means that you have all the PIs for that PO. add all the POs and you ave your result set.
You will need a count of the items in your list, i.e. #list_count. Figure out which Offerings have Instances that aren't in the list. Select all Offerings that aren't in that list and do have Instances in the list:
select P0,count(*) c from table where P0 not in (
select P0 from table where P1 not in (#list)
) and P1 in (#list) group by P0
I would store that in a temp table and select * records where c = #list_count
If we redefine a bit a problem:
Lets have a customer table with product instances:
crete table cust_pi (
pi varchar(5),
customer varchar(5));
And a "product_catalogue" table:
CREATE TABLE PI_PO_TEST
("PO" VARCHAR2(5 CHAR),
"PI" VARCHAR2(5 CHAR)
);
Lets fill it with some sample data:
insert into CUST_PI (PI, CUSTOMER)
values ('11', '1');
insert into CUST_PI (PI, CUSTOMER)
values ('10', '1');
insert into CUST_PI (PI, CUSTOMER)
values ('12', '1');
insert into CUST_PI (PI, CUSTOMER)
values ('13', '1');
insert into CUST_PI (PI, CUSTOMER)
values ('14', '1');
insert into PI_PO_TEST (PO, PI)
values ('A', '10');
insert into PI_PO_TEST (PO, PI)
values ('A', '11');
insert into PI_PO_TEST (PO, PI)
values ('A', '12');
insert into PI_PO_TEST (PO, PI)
values ('A', '13');
insert into PI_PO_TEST (PO, PI)
values ('B', '14');
insert into PI_PO_TEST (PO, PI)
values ('C', '11');
insert into PI_PO_TEST (PO, PI)
values ('C', '12');
insert into PI_PO_TEST (PO, PI)
values ('D', '15');
insert into PI_PO_TEST (PO, PI)
values ('D', '14');
Then my first shoot solution is like this:
select po1 po /* select all product offerings that match the product definition
(i.e. have the same number of product instances per offering as
in product catalogue */
from (select po po1, count(c.pi) k1
from cust_pi c, pi_po_test t
where c.pi = t.pi
and customer = 1
group by po) t1,
(select po po2, count(*) k2 from pi_po_test group by po) t2
where k1 = k2
and po1 = po2
minus /* add those, that are contained within others */
select slave
from (select po2 master, po1 slave
/* this query returns, that if you have po "master" slave should be removed from result,
as it is contained within*/
from (select t1.po po1, t2.po po2, count(t1.po) k1
from pi_po_test t1, pi_po_test t2
where t1.pi = t2.pi
group by t1.po, t2.po) t1,
(select po, count(po) k2 from pi_po_test group by po) t2
where t1.po2 = t2.po
and k1 < k2)
where master in
/* repeated query from begining. This could be done better :-) */
(select po1 po
from (select po po1, count(c.pi) k1
from cust_pi c, pi_po_test t
where c.pi = t.pi
and customer = 1
group by po) t1,
(select po po2, count(*) k2 from pi_po_test group by po) t2
where k1 = k2
and po1 = po2)
All of that was done on Oracle, so your mileage may vary
I tested this under 4 sets of values and they all returned a correct result. This uses a function that I use in SQL to generate a table from a string of parameters separated by semicolons.
DECLARE #tbl TABLE (
po varchar(10),
pii int)
INSERT INTO #tbl
SELECT 'A', 10
UNION ALL
SELECT 'A', 11
UNION ALL
SELECT 'A', 12
UNION ALL
SELECT 'B', 10
UNION ALL
SELECT 'B', 11
UNION ALL
SELECT 'C', 13
DECLARE #value varchar(100)
SET #value = '10;11;12;'
--SET #value = '11;10;'
--SET #value = '13;'
--SET #value = '10;'
SELECT DISTINCT po
FROM #tbl a
INNER JOIN fMultiValParam (#value) p ON
a.pii = p.paramid
WHERE a.po NOT IN (
SELECT t.po
FROM #tbl t
LEFT OUTER JOIN (SELECT *
FROM #tbl tt
INNER JOIN fMultiValParam (#value) p ON
tt.pii = p.paramid) tt ON
t.pii = tt.pii
AND t.po = tt.po
WHERE tt.po IS NULL)
here's the function
CREATE FUNCTION [dbo].[fMultiValParam]
(#Param varchar(5000))
RETURNS #tblParam TABLE (ParamID varchar(40))
AS
BEGIN
IF (#Param IS NULL OR LEN(#Param) < 2)
BEGIN
RETURN
END
DECLARE #len INT
DECLARE #index INT
DECLARE #nextindex INT
SET #len = DATALENGTH(#Param)
SET #index = 0
SET #nextindex = 0
WHILE (#index < #len)
BEGIN
SET #Nextindex = CHARINDEX(';', #Param, #index)
INSERT INTO #tblParam
SELECT SUBSTRING(#Param, #index, #nextindex - #index)
SET #index = #nextindex + 1
END
RETURN
END
Try this:
SELECT DISTINCT COALESCE ( offer, NULL )
FROM products
WHERE instance IN ( #instancelist )
IMHO impossible via pure SQL without some stored-procedure code. But... i'm not sure.
Added: On the other hand, I'm getting an idea about a recursive query (in MSSQL 2005 there is such a thing, which allows you to join a query with it's own results until there are no more rows returned) which might "gather" the correct answers by cross-joining the results of previous step with all products and then filtering out invalid combinations. You would however get all permutations of valid combinations and it would hardly be efficient. And the idea is pretty vague, so I can't guarantee that it can actually be implemented.