Salve a tutti,
considerando il "filtro di ricerca" come una concatenazione di [col1], quindi "A-B-C-????" separati da "-" o altro separatore,' possiamo tokenizzare la "lista" in un insieme di righe da poter utilizzare in JOIN con la tabella principale.
quindi, raggruppando per data (Col2) il prodotto della JOIN filtriamo il risultato raggruppato' per i soli risultati che referenzino TUTTI i Token ottenuti, e da cio' richiediamo la data minima...
con le Common Table Expressions possiamo "spezzettare" in forma a noi conveniente le varie sub query che effettuano l'intera operazione ad esempio come di seguito:
consideriamo l'insieme
INSERT INTO dbo.t
VALUES ( 'A', '2019-05-18' ), ( 'A', '2019-05-19' ), ( 'A', '2019-05-20' ), ( 'A', '2019-05-21' ), ( 'A', '2019-05-22' )
, ( 'B', '2019-05-19' ), ( 'B', '2019-05-20' ), ( 'B', '2019-05-21' ), ( 'B', '2019-05-22' )
, ( 'C', '2019-05-21' ), ( 'C', '2019-05-22' )
, ( 'D', '2019-05-20' ), ( 'D', '2019-05-21' ), ( 'D', '2019-05-22' );
dove, come indicato, tokenizziamo il "filtro di ricerca" {concatenazione di [col1], quindi "A-B-C-????" separati da "-" o altro separatore} in un set come
DECLARE @colFilterList varchar(8000) = 'A-B-C';
DECLARE @sep char(1) = '-';
PRINT 'possiamo tokenizzare la "lista" in un insieme di righe da poter utilizzare in JOIN con la tabella principale:';
WITH Pieces(pn, startPos, endPos, flgList) AS (
SELECT 1, 1, CHARINDEX(@sep, @colFilterList), @colFilterList AS flgList
UNION ALL
SELECT pn + 1, endPos + 1, CHARINDEX(@sep, Pieces.flgList , endPos + 1), Pieces.flgList
FROM Pieces
WHERE endPos > 0
),
cteAllGroups AS (
SELECT LTRIM(RTRIM(SUBSTRING(Pieces.flgList, startPos, CASE WHEN endPos > 0 THEN endPos-startPos ELSE 8000 END))) AS [Col1]
FROM Pieces
)
SELECT * FROM cteAllGroups;
e quindi, per finire:
PRINT 'quindi, raggruppando per data (Col2) il prodotto della JOIN filtriamo il risultato raggruppato'
PRINT ' per i soli risultati che referenzino tutti i Token ottenuti quindi:-> HAVING COUNT(*) = (SELECT COUNT(*) FROM cteAllGroups)';
PRINT ' e quindi richiediamo la data minima del set restituito';
WITH Pieces(pn, startPos, endPos, flgList) AS (
SELECT 1, 1, CHARINDEX(@sep, @colFilterList), @colFilterList AS flgList
UNION ALL
SELECT pn + 1, endPos + 1, CHARINDEX(@sep, Pieces.flgList , endPos + 1), Pieces.flgList
FROM Pieces
WHERE endPos > 0
),
cteAllGroups AS (
SELECT LTRIM(RTRIM(SUBSTRING(Pieces.flgList, startPos, CASE WHEN endPos > 0 THEN endPos-startPos ELSE 8000 END))) AS [Col1]
FROM Pieces
),
cteGroupByDate AS (
SELECT MIN(t.[col2]) AS [col2]
FROM dbo.t t
JOIN cteAllGroups c ON t.[col1] = c.[Col1]
GROUP BY t.[col2]
HAVING COUNT(*) = (SELECT COUNT(*) FROM cteAllGroups)
)
SELECT MIN(c.[col2]) AS [col2]
FROM cteGroupByDate c;
--<-----------------
considerando il filtro di ricerca come una concatenazione di [col1], quindi "A-B-C-????" separati da "-" o altro separatore,
tokenizedFilter
----------------
A-B-C
possiamo tokenizzare la "lista" in un insieme di righe da poter utilizzare in JOIN con la tabella principale:
Col1
----
A
B
C
quindi, raggruppando per data (Col2) il prodotto della JOIN filtriamo il risultato raggruppato
per i soli risultati che referenzino tutti i Token ottenuti HAVING COUNT(*) = (SELECT COUNT(*) FROM cteAllGroups)
e quindi richiediamo la data minima del set restituito
col2
----------
2019-05-21
saluti omnia
--
Andrea