Benutzer mit den meisten Antworten
Frage zu T-SQL: Hilfe bei einer schwierigen Abfrage

Frage
-
Hallo an alle!
Ich habe heute ein Problem mit einer sehr speziellen Abfrage, die ich auf dem SQl Server 2005 erstellen muss.
In meinem View habe ich Artikel, Menge, Typ und Vermietungszeitraum gelistet (und andere Werte). Diesen View filtere ich noch auf einen bestimmten Artikelnamen und einen bestimmten Monat (z.B. August 2015). So weit, so gut.
Jetzt brauche ich aber die maximale Anzahl an Artikeln mit dem Typ 'F' die gleichzeitig vermietet wurden. Die Vermietungszeiträume können sich durchaus überschneiden. Ich habe in meinem Beispiel 5 Zeiträume ermittelt, wo sich die Vermietung überschneidet.
Ich bräuchte jetzt einen Algorhythmus, der mir für jeden der 5 Schnittmengen die maximale Anzahl an Typ 'F' Artikeln ermittelt und mir den größten davon zurück gibt.
Ich hoffe das war verständlich. Kann mir da jemand einen Tipp geben?
Antworten
-
Hallo Thorsten,
dann fehlt wahrscheinlich noch die Einschränkung AND (Artikelname = @Art)
Also komplett dann so:
SELECT @Fremd = MAX(ANZAHL) FROM ( SELECT COUNT(*) AS ANZAHL ,DATEPART(day, LS_Datum) FROM dbo.View_StatistikArtikel WHERE ( (DATEPART(year, LS_Datum) = @Jahr) AND (DATEPART(month, LS_Datum) = @Monat) OR (DATEPART(year, LS_Rück_Datum) = @Jahr) AND (DATEPART(month, LS_Rück_Datum) = @Monat) ) AND (LS_Rück_Datum IS NOT NULL) AND (Artikeltyp = N'F') AND (Auftragsnr > 40000) AND (Anzahl > 0) AND (Artikelname = @Art) GROUP BY DATEPART(day, LS_Datum) ) AS FremdSub
Grüße
Olli
- Als Antwort markiert Thorsten Schröer Freitag, 18. September 2015 06:46
Alle Antworten
-
Hallo Thorsten,
für mich war es nicht verständlich.
Poste bitte die Tabellendefinition (als CREATE TABLE Statement), einige Beispieldaten (als INSERT INTO Statement) sowie die gewünschte Ausgabe anhand der Beispieldaten.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community -
Hallo Steffan,
ich versuchs mal.
Die View auf der diese spezielle Abfrage erstellt werden soll sieht so aus:
SELECT Auftragsnr, Artikelname, Anzahl, Anz_Miettage, Preis_DM, Artikeltyp, LS_Datum, LS_Rück_Datum, Plan_LS_Datum, Plan_Rück_Datum FROM dbo.Auftrag_Einzelpos_Artikel WHERE (Auftragsnr > 40000) AND ((DATEPART(year, LS_Datum) >= 2014) OR (DATEPART(year, LS_Rück_Datum) >= 2014)) AND (Artikeltyp <> '9') AND (Plan_LS_Datum IS NOT NULL) AND (Plan_Rück_Datum IS NOT NULL) UNION SELECT Auftragsnr, Artikelname, Anzahl, Anz_Miettage, Preis_DM, Artikeltyp, LS_Datum, LS_Rück_Datum, Plan_LS_Datum, Plan_Rück_Datum FROM dbo.View_Auftrag_Einzelpos_Artikel_Archiv WHERE (Auftragsnr > 40000) AND ((DATEPART(year, LS_Datum) >= 2014) OR (DATEPART(year, LS_Rück_Datum) >= 2014)) AND (Artikeltyp <> '9') AND (Plan_LS_Datum IS NOT NULL) AND (Plan_Rück_Datum IS NOT NULL)
Die Daten: (Bitte nicht an DM stören, die DB ist rel. alt)
AuftrNR; Artikelname; Anzahl; Anz_Miettage ; Preis_DM; Artikeltyp; LS_Datum; LS_Rück_Datum; Plan_LS-Datum; Plan_Rück_Datum
68780 HMI-Verlängerungskabel 575/M8/1,2/1,8 KW ARRI 7m 2 2,5 5,0000 L 31.03.2014 00:00:00 07.04.2014 15:00:01 31.03.2014 09:00:00 04.04.2014 08:00:00 68780 HMI-Verlängerungskabel 9/6KW ARRI 10m 5 2,5 0,0000 F 31.03.2014 00:00:00 04.04.2014 14:35:12 31.03.2014 09:00:00 04.04.2014 08:00:00
Diese Daten werden mit einer stored proc gelesen, ein paar Daten berechnet und dann in eine Statistik-Tabelle gespeichert.
Die Zieltabelle sieht so aus:
CREATE TABLE [dbo].[Statistik_Artikel]( [ID] [bigint] IDENTITY(1,1) NOT NULL, [Artikelname_d] [nvarchar](62) NOT NULL, [Anzahl] [int] NULL, [Bestand] [int] NULL, [AnzahlFremd] [int] NULL, [Preis] [money] NULL, [Wert_Versicherung] [money] NULL, [Wert_Anschaffung] [money] NULL, [Summe_Miettage] [int] NULL, [Anzahl_Miettage] [real] NULL, [Auslastung] [real] NULL, [Fremdquote] [real] NULL, [AnzArtikelUnterwegs] [int] NULL, [Jahr] [int] NULL, [Monat] [int] NULL, CONSTRAINT [PK_Statistik_Artikel] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 75) ON [PRIMARY] ) ON [PRIMARY]
und meine stored proc so:
CREATE PROCEDURE [dbo].[StatistikArtikelUpdate] @Jahr int, @Monat int AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON; declare @Jahrtage int; set @Jahrtage = 365; declare @Entkäfern bit; set @Entkäfern = 0; declare @dtMonatsanfang datetime; declare @dtMonatsende datetime; declare @AnzTageMonat int; declare @Tag1 datetime; declare @Tag2 datetime; declare @Art nvarchar(62); declare @Bestand int; declare @WertVers money; declare @WertAnsch money; declare @Anzahl int; declare @Preis money; declare @SumMiet int; declare @SumMiet1 int; declare @AnzMiet real; declare @Auslastung real; declare @Fremd real; declare @AnzFremd int; declare @AnzUnterwegs int; declare @Datum1 datetime; declare @Datum2 datetime; declare @Auftr int; declare @Anz int; declare @ID bigint; ---------------------- set @Art = ''; set @Bestand = -1; set @WertVers = -1; set @WertAnsch = -1; ---------------------- declare cur cursor for SELECT DISTINCT Artikelname_d, Wert_Versicherung, Wert_Anschaffung, Bestand FROM Artikel; open cur; fetch next from cur into @Art, @WertVers, @WertAnsch, @Bestand; select @dtMonatsanfang = CAST(STR(@Jahr * 10000 + @Monat * 100 + 1) AS DATETIME) select @dtMonatsende = CONVERT(VARCHAR(12), DATEADD(MONTH,DATEDIFF(MONTH,0,@dtMonatsanfang),30), 104) select @AnzTageMonat = 32 - day(@dtMonatsanfang - day(@dtMonatsanfang) + 32); while @@fetch_status = 0 begin set @Anzahl = -1; --set @Anzahl1 = -1; --set @Anzahl2 = -1; set @Preis = -1; --set @Preis1 = -1; --set @Preis2 = -1; set @SumMiet = -1; set @SumMiet1 = -1; --set @SumMiet2 = -1; set @AnzMiet = -1; --set @AnzMiet1 = -1; --set @AnzMiet2 = -1; set @Auslastung = -1; set @Fremd = -1; set @AnzFremd = -1; --set @AnzFremd1 = -1; --set @AnzFremd2 = -1; set @AnzUnterwegs = -1; --zum debuggen benötigt if @Art = N'Velvet 2 Netzteil' set @Entkäfern = 1; if @Entkäfern = 1 begin print '*********'; print 'Jahr: ' + cast(@Jahr as nvarchar); print 'Monat: ' + cast(@Monat as nvarchar); print '@dtMonatsanfang: ' + cast(@dtmonatsanfang as nvarchar); print '@dtMonatsende: ' + cast(@dtMonatsende as nvarchar); print 'Anzahl Tage im Monat: ' + cast(@AnzTageMonat as nvarchar); end if @Entkäfern = 1 begin print 'Artikelname: ' + @Art; print 'Bestand: ' + cast(@Bestand as nvarchar); end --@Anzahl SELECT @Anzahl = ISNULL(SUM(ISNULL(Anzahl, 0)), 0) FROM dbo.View_StatistikArtikel -- Auftrag_Einzelpos_Artikel WHERE (Auftragsnr > 40000) AND ((DATEPART(year, LS_Datum) = @Jahr) AND (DATEPART(month, LS_Datum) = @Monat) OR (DATEPART(year, LS_Rück_Datum) = @Jahr) AND (DATEPART(month, LS_Rück_Datum) = @Monat)) AND (LS_Rück_Datum is not null) AND (Artikelname = @Art) AND (Anzahl > 0) AND (Artikeltyp <> 'V'); --set @Anzahl = ISNULL(@Anzahl1, 0) --+ ISNULL(@Anzahl2, 0); if @Entkäfern = 1 begin --print 'Anzahl1 = ' + cast(@Anzahl1 as nvarchar); --print 'Anzahl2 = ' + cast(@Anzahl2 as nvarchar); print 'Anzahl = ' + cast(@Anzahl as nvarchar); print '---' end --@Preis SELECT @Preis = ISNULL(SUM(ISNULL(Preis_DM, 0)), 0) FROM dbo.View_StatistikArtikel -- Auftrag_Einzelpos_Artikel WHERE (Auftragsnr > 40000) AND ((DATEPART(year, LS_Datum) = @Jahr) AND (DATEPART(month, LS_Datum) = @Monat) OR (DATEPART(year, LS_Rück_Datum) = @Jahr) AND (DATEPART(month, LS_Rück_Datum) = @Monat)) AND (LS_Rück_Datum is not null) AND (Artikelname = @Art) AND (Anzahl > 0) AND (Artikeltyp <> 'V'); --set @Preis = ISNULL(@Preis1, 0) --+ ISNULL(@Preis2, 0); if @Entkäfern = 1 begin --print 'Preis1 = ' + cast(@Preis1 as nvarchar); --print 'Preis2 = ' + cast(@Preis2 as nvarchar); print 'Preis = ' + cast(@Preis as nvarchar); print '---' end --@AnzMiet SELECT @AnzMiet = ISNULL(SUM(ISNULL(Anz_Miettage, 0)), 0) FROM dbo.View_StatistikArtikel -- Auftrag_Einzelpos_Artikel WHERE (Auftragsnr > 40000) AND ((DATEPART(year, LS_Datum) = @Jahr) AND (DATEPART(month, LS_Datum) = @Monat) OR (DATEPART(year, LS_Rück_Datum) = @Jahr) AND (DATEPART(month, LS_Rück_Datum) = @Monat)) AND (LS_Rück_Datum is not null) AND (Artikelname = @Art) AND (Anzahl > 0) AND (Artikeltyp <> 'V'); --set @AnzMiet = ISNULL(@AnzMiet1, 0) --+ ISNULL(@AnzMiet2, 0); if @Entkäfern = 1 begin --print 'AnzMiet1 = ' + cast(@AnzMiet1 as nvarchar); --print 'AnzMiet2 = ' + cast(@AnzMiet2 as nvarchar); print 'AnzMiet = ' + cast(@AnzMiet as nvarchar); print '---' end --@SumMiet if @Entkäfern = 1 begin print '-> Schleife über die SumMiet'; end declare curSumMiet cursor for select Auftragsnr, Anzahl, LS_Datum, LS_Rück_Datum FROM dbo.View_StatistikArtikel WHERE (Auftragsnr > 40000) AND ((DATEPART(year, LS_Datum) = @Jahr) AND (DATEPART(month, LS_Datum) = @Monat) OR (DATEPART(year, LS_Rück_Datum) = @Jahr) AND (DATEPART(month, LS_Rück_Datum) = @Monat)) AND (LS_Rück_Datum is not null) AND (Artikelname = @Art) AND (Anzahl > 0) AND (Artikeltyp <> 'V'); set @SumMiet1 = 0; open curSumMiet; fetch next from curSumMiet into @Auftr, @Anz, @Datum1, @Datum2; while @@fetch_status = 0 begin if @Datum1 < @dtMonatsanfang set @Tag1 = @dtmonatsanfang; else set @Tag1 = @Datum1; if @Datum2 > @dtMonatsende set @Tag2 = @dtMonatsende; else set @Tag2 = @Datum2; set @SumMiet1 = @SumMiet1 + (@Anz * (DATEDIFF(day, @Tag1, @Tag2) + 1)) if @Entkäfern = 1 begin print 'Auftragsnr: ' + cast(@Auftr as nvarchar); print 'Anzahl: ' + cast(@Anz as nvarchar); print 'von Tag ' + convert(nvarchar, @Tag1, 104) + ' bis Tag ' + convert(nvarchar, @Tag2, 104) print 'sind ' + cast((DATEDIFF(day, @Tag1, @Tag2) + 1) as nvarchar) + ' Tage' print 'macht ' + cast((@Anz * (DATEDIFF(day, @Tag1, @Tag2) + 1)) as nvarchar) + ' Tage' end fetch next from curSumMiet into @Auftr, @Anz, @Datum1, @Datum2; end close curSumMiet; deallocate curSumMiet; set @SumMiet = ISNULL(@SumMiet1, 0) --+ ISNULL(@SumMiet2, 0); if @Entkäfern = 1 begin --print 'SumMiet1 = ' + cast(@SumMiet1 as nvarchar); --print 'SumMiet2 = ' + cast(@SumMiet2 as nvarchar); print 'SumMiet = ' + cast(@SumMiet as nvarchar); print '---' end --@Bestand if @Bestand > 0 begin set @Auslastung = (CAST(@SumMiet as real) * 100.0) / (CAST(@Bestand as real) * CAST(@AnzTageMonat as real)); end if @Entkäfern = 1 begin print '(CAST(@SumMiet as real) * 100.0): ' + cast((CAST(@SumMiet as real) * 100.0) as nvarchar); print '(CAST(@Bestand as real) * CAST(@AnzTageMonat as real)): '-- + cast((CAST(@Bestand as real) * CAST(@AnzTageMonat as real)) as nvarchar); print '(' + CAST(CAST(@Bestand as real) as nvarchar) + ' * ' + CAST(CAST(@AnzTageMonat as real) as nvarchar) + '): ' + cast((CAST(@Bestand as real) * CAST(@AnzTageMonat as real)) as nvarchar); print 'Auslastung = ' + cast(@Auslastung as nvarchar); print '---' end --@AnzFremd SELECT DISTINCT @AnzFremd = ISNULL(SUM(ISNULL(Anzahl, 0)), 0) FROM dbo.View_StatistikArtikel -- Auftrag_Einzelpos_Artikel WHERE ((DATEPART(year, LS_Datum) = @Jahr) AND (DATEPART(month, LS_Datum) = @Monat) OR (DATEPART(year, LS_Rück_Datum) = @Jahr) AND (DATEPART(month, LS_Rück_Datum) = @Monat)) AND (LS_Rück_Datum is not null) AND (Artikeltyp = N'F') AND (Auftragsnr > 40000) AND (Artikelname = @Art) AND (Anzahl > 0) --set @AnzFremd = ISNULL(@AnzFremd1, 0) --+ ISNULL(@AnzFremd2, 0); if @Entkäfern = 1 begin --print 'AnzFremd1 = ' + cast(@AnzFremd1 as nvarchar); --print 'AnzFremd2 = ' + cast(@AnzFremd2 as nvarchar); print 'AnzFremd = ' + cast(@AnzFremd as nvarchar); print '---' end set @Fremd = -1; --@AnzFremd; --@AnzUnterwegs SELECT DISTINCT @AnzUnterwegs = ISNULL(SUM(ISNULL(Anzahl, 0)), 0) FROM dbo.View_StatistikArtikel -- Auftrag_Einzelpos_Artikel WHERE (DATEPART(year, LS_Datum) = @Jahr) AND (DATEPART(month, LS_Datum) = @Monat) AND (LS_Rück_Datum is null) AND (Auftragsnr > 40000) AND (Artikelname = @Art) AND (Anzahl > 0) AND (Artikeltyp <> 'V'); --- set @ID = -1; select @ID = isnull(ID, -1) from dbo.Statistik_Artikel where (Artikelname_d = @Art) AND (Jahr = @Jahr) and (Monat = @Monat); --print '@Art = ' + @Art; --print '@Jahr = ' + cast(@Jahr as nvarchar); --print '@Monat = ' + cast(@Monat as nvarchar); --print '@ID = ' + cast(@ID as nvarchar); if @ID = -1 begin insert into dbo.Statistik_Artikel(Artikelname_d, Preis, Wert_Versicherung, Wert_Anschaffung, Summe_Miettage, Anzahl_Miettage, Auslastung, Fremdquote, Jahr, Monat, Anzahl, Bestand, AnzahlFremd, AnzArtikelUnterwegs) values(@Art, @Preis, @WertVers, @WertAnsch, @SumMiet, @AnzMiet, @Auslastung, @Fremd, @Jahr, @Monat, @Anzahl, @Bestand, @AnzFremd, @AnzUnterwegs); --print 'inserted'; end else begin update dbo.Statistik_Artikel set Preis = @Preis, Wert_Versicherung = @WertVers, Wert_Anschaffung = @WertAnsch, Summe_Miettage = @SumMiet, Anzahl_Miettage = @AnzMiet, Auslastung = @Auslastung, Fremdquote = @Fremd, Bestand = @Bestand, AnzahlFremd = @AnzFremd, AnzArtikelUnterwegs = @AnzUnterwegs where ID = @ID; --print 'updated'; end fetch next from cur into @Art, @WertVers, @WertAnsch, @Bestand; end --ENDE Cursour-Schleife close cur; deallocate cur; END
An dieser Stelle "set @Fremd = -1;" brauche ich jetzt irgendeine Funktion / Abfrage / o.ä. die mir angibt, wie viele Fremdartikel ich ein einem Tag maximal habe.
Ich kann es irgendwie nicht besser ausdrücken, aber hoffe, dass es jetzt etwas verständlicher ist.
-
Okay,
möchtest du jetzt wissen, wie viel du verliehen hast oder wie viel noch im Bestand sind.
Willst du das pro Tag wissen (wo ist dann die Variable, für den Tag) oder möchtest du wissen wie der maximale Wert pro Tag innerhalb eines Monats ist.
-
Hi,
dann sollte es damit klappen:
SELECT @Fremd = MAX(ANZAHL) FROM ( SELECT COUNT(*) AS ANZAHL ,DATEPART(day, LS_Datum) FROM dbo.View_StatistikArtikel WHERE ( (DATEPART(year, LS_Datum) = @Jahr) AND (DATEPART(month, LS_Datum) = @Monat) OR (DATEPART(year, LS_Rück_Datum) = @Jahr) AND (DATEPART(month, LS_Rück_Datum) = @Monat) ) AND (LS_Rück_Datum IS NOT NULL) AND (Artikeltyp = N'F') AND (Auftragsnr > 40000) AND (Anzahl > 0) GROUP BY DATEPART(day, LS_Datum) ) AS FremdSub
Grüße
Olli
-
Ich habe das Beispiel mal stark vereinfacht und auf wenige Datensätze reduziert. Vielleicht kommst Du ja mit diesem Ansatz weiter?
Declare @Daten as Table(Artikel varchar(20), Menge int, Typ char(1), Vermietungszeitraum_Start Date, Vermietungszeitraum_Ende Date); Declare @StartDate date = '2015-01-01', @EndDate date = '2015-12-31'; Insert into @Daten(Artikel, Menge, Typ, Vermietungszeitraum_Start, Vermietungszeitraum_Ende) Values ('Artikel 1 Z1', 1, 'F', '2015-08-01', '2015-08-09'); Insert into @Daten(Artikel, Menge, Typ, Vermietungszeitraum_Start, Vermietungszeitraum_Ende) Values ('Artikel 1 Z2', 1, 'F', '2015-08-02', '2015-08-09'); Insert into @Daten(Artikel, Menge, Typ, Vermietungszeitraum_Start, Vermietungszeitraum_Ende) Values ('Artikel 2 Z1', 1, 'F', '2015-08-03', '2015-08-10'); Insert into @Daten(Artikel, Menge, Typ, Vermietungszeitraum_Start, Vermietungszeitraum_Ende) Values ('Artikel 1 Z3', 1, 'F', '2015-08-09', '2015-08-19'); Insert into @Daten(Artikel, Menge, Typ, Vermietungszeitraum_Start, Vermietungszeitraum_Ende) Values ('Artikel 1 Z4', 1, 'F', '2015-08-12', '2015-08-17'); Insert into @Daten(Artikel, Menge, Typ, Vermietungszeitraum_Start, Vermietungszeitraum_Ende) Values ('Artikel 2 Z2', 1, 'F', '2015-08-20', '2015-08-30'); Insert into @Daten(Artikel, Menge, Typ, Vermietungszeitraum_Start, Vermietungszeitraum_Ende) Values ('Artikel 3 Z1', 1, 'G', '2015-08-02', '2015-08-09'); Select Artikel, Menge, Typ, Vermietungszeitraum_Start, Vermietungszeitraum_Ende from @Daten Where Typ = 'F'; WITH Kalender AS ( SELECT @StartDate AS [Tag] UNION ALL SELECT DATEADD(dd, 1, [Tag]) FROM Kalender WHERE DATEADD(dd, 1, [Tag] ) <= @EndDate ) Select Artikel, Menge, Typ, Vermietungszeitraum_Start, Vermietungszeitraum_Ende, k.Tag from @Daten d inner join Kalender k on k.Tag between d.Vermietungszeitraum_Start and d.Vermietungszeitraum_Ende Where d.Typ = 'F' ORDER BY d.Artikel, k.Tag OPTION ( MAXRECURSION 0 ) -- Ohne diesen Hinweis würde die Rekursion bei 100 Tagen stoppen. Fatal bei einem längeren Zeitraum. ; WITH Kalender AS ( SELECT @StartDate AS [Tag] UNION ALL SELECT DATEADD(dd, 1, [Tag]) FROM Kalender WHERE DATEADD(dd, 1, [Tag] ) <= @EndDate ), Vorberechnung as ( Select Artikel, Menge, Typ, Vermietungszeitraum_Start, Vermietungszeitraum_Ende, k.Tag from @Daten d inner join Kalender k on k.Tag between d.Vermietungszeitraum_Start and d.Vermietungszeitraum_Ende Where d.Typ = 'F' ) Select Tag, count(*) 'Anzahl gleichzeitige Vermietungen' from Vorberechnung group by Tag order by Tag OPTION ( MAXRECURSION 0 ) -- Ohne diesen Hinweis würde die Rekursion bei 100 Tagen stoppen. Fatal bei einem längeren Zeitraum. ; WITH Kalender AS ( SELECT @StartDate AS [Tag] UNION ALL SELECT DATEADD(dd, 1, [Tag]) FROM Kalender WHERE DATEADD(dd, 1, [Tag] ) <= @EndDate ), Vorberechnung as ( Select Artikel, Menge, Typ, Vermietungszeitraum_Start, Vermietungszeitraum_Ende, k.Tag from @Daten d inner join Kalender k on k.Tag between d.Vermietungszeitraum_Start and d.Vermietungszeitraum_Ende Where d.Typ = 'F' ), Anzahlen as ( Select Tag, count(*) Anzahl_gleichzeitige_Vermietungen from Vorberechnung group by Tag ) Select max(Anzahl_gleichzeitige_Vermietungen) as Maximum from Anzahlen where Tag between '2015-08-07' and '2015-08-17' OPTION ( MAXRECURSION 0 ) -- Ohne diesen Hinweis würde die Rekursion bei 100 Tagen stoppen. Fatal bei einem längeren Zeitraum. ;
Einen schönen Tag noch,Christoph--Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu- Als Antwort vorgeschlagen Dimitar DenkovMicrosoft contingent staff, Administrator Montag, 14. September 2015 09:57
-
Hallo Olli,
ich bin erst jetzt dazu gekommen, dass zu testen. Deine Abfrage ist schön kurz und knackig, nur scheint sie leider nicht zu funktionieren. Ich bekomme bei jedem (wirklich jedem) Artikel den Wert 123. Das kann nicht stimmen. Selbst bei Artikeln ohne Fremdanteil bekomme ich diesen Wert.
Viele Grüße
Thorsten
Thorsten Schröer Dipl-Inform (FH) - EDV, Beratung & Service - double-D-IT -Office- / Information system support Bismarckstraße 18a Germany-12169 Berlin Steglitz phone: +49-(0)30-303286770 fax: +49-(0)30-303286779
-
Hallo Christoph,
na Dein Ansatz ist ja sehr kompliziert und komplex. Ich habe es mal versucht für meinen Fall anzupassen und bekomme eine Fehlermeldung.
Hier erst einmal meine Version:
Select Artikelname, Anzahl, Artikeltyp, Plan_LS_Datum, Plan_Rück_Datum from dbo.View_StatistikArtikel Where Artikeltyp = 'F'; WITH Kalender AS ( SELECT '2015-08-01' AS [Tag] UNION ALL SELECT DATEADD(dd, 1, [Tag]) FROM Kalender WHERE DATEADD(dd, 1, [Tag] ) <= '2015-08-31' ) Select Artikelname, Anzahl, Artikeltyp, Plan_LS_Datum, Plan_Rück_Datum, k.Tag from dbo.View_StatistikArtikel d inner join Kalender k on k.Tag between d.Plan_LS_Datum and d.Plan_Rück_Datum Where d.Artikeltyp = 'F' ORDER BY d.Artikelname, k.Tag OPTION ( MAXRECURSION 0 ) -- Ohne diesen Hinweis würde die Rekursion bei 100 Tagen stoppen. Fatal bei einem längeren Zeitraum. ; WITH Kalender AS ( SELECT '2015-08-01' AS [Tag] UNION ALL SELECT DATEADD(dd, 1, [Tag]) FROM Kalender WHERE DATEADD(dd, 1, [Tag] ) <= '2015-08-31' ), Vorberechnung as ( Select Artikelname, Anzahl, Artikeltyp, Plan_LS_Datum, Plan_Rück_Datum, k.Tag from dbo.View_StatistikArtikel d inner join Kalender k on k.Tag between d.Plan_LS_Datum and d.Plan_Rück_Datum Where d.Artikeltyp = 'F' ) Select Tag, count(*) as 'Anzahl gleichzeitige Vermietungen' from Vorberechnung group by Tag order by Tag OPTION ( MAXRECURSION 0 ) -- Ohne diesen Hinweis würde die Rekursion bei 100 Tagen stoppen. Fatal bei einem längeren Zeitraum. ; WITH Kalender AS ( SELECT '2015-08-01' AS [Tag] UNION ALL SELECT DATEADD(dd, 1, [Tag]) FROM Kalender WHERE DATEADD(dd, 1, [Tag] ) <= '2015-08-31' ), Vorberechnung as ( Select Artikelname, Anzahl, Artikeltyp, Plan_LS_Datum, Plan_Rück_Datum, k.Tag from dbo.View_StatistikArtikel d inner join Kalender k on k.Tag between d.Plan_LS_Datum and d.Plan_Rück_Datum Where d.Artikeltyp = 'F' ), Anzahlen as ( Select Tag, count(*) as 'Anzahl_gleichzeitige_Vermietungen' from Vorberechnung group by Tag ) Select max('Anzahl_gleichzeitige_Vermietungen') as Maximum from Anzahlen where Tag between '2015-08-01' and '2015-08-31' OPTION ( MAXRECURSION 0 ) -- Ohne diesen Hinweis würde die Rekursion bei 100 Tagen stoppen. Fatal bei einem längeren Zeitraum. ;
Und das ist die Fehlermeldung:
Meldung 240, Ebene 16, Status 1, Zeile 7
Die Typen stimmen zwischen dem Anker und dem rekursiven Teil in der "Tag"-Spalte der rekursiven Abfrage "Kalender" nicht überein.Da ich leider Deinen Ansatz nicht recht verstehe, weiß ich auch nicht, wo mein Fehler ist. Ich muss dazu sagen, dass ich kein SQL-Experte bin und es meistens nur mit rel. einfachen Abfragen zutun habe.
Vielleicht hast Du ja eine Idee.
Viele Grüße
Thorsten
Thorsten Schröer Dipl-Inform (FH) - EDV, Beratung & Service - double-D-IT -Office- / Information system support Bismarckstraße 18a Germany-12169 Berlin Steglitz phone: +49-(0)30-303286770 fax: +49-(0)30-303286779
-
Hallo Thorsten,
dann fehlt wahrscheinlich noch die Einschränkung AND (Artikelname = @Art)
Also komplett dann so:
SELECT @Fremd = MAX(ANZAHL) FROM ( SELECT COUNT(*) AS ANZAHL ,DATEPART(day, LS_Datum) FROM dbo.View_StatistikArtikel WHERE ( (DATEPART(year, LS_Datum) = @Jahr) AND (DATEPART(month, LS_Datum) = @Monat) OR (DATEPART(year, LS_Rück_Datum) = @Jahr) AND (DATEPART(month, LS_Rück_Datum) = @Monat) ) AND (LS_Rück_Datum IS NOT NULL) AND (Artikeltyp = N'F') AND (Auftragsnr > 40000) AND (Anzahl > 0) AND (Artikelname = @Art) GROUP BY DATEPART(day, LS_Datum) ) AS FremdSub
Grüße
Olli
- Als Antwort markiert Thorsten Schröer Freitag, 18. September 2015 06:46
-
Hallo Thorsten,
rekursive CTEs sind sehr pingelig, was die Datentypen angeht. In meinem Beispiel waren es beide Dates, Du versuchst eine implizite Konvertierung eines Strings, was in diesem Falle nicht geht. Also bitte schön typkonform casten!
Einen schönen Tag noch,Christoph--Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu -
Guten Morgen Olli,
da hätte ich auch selber draufkommen können ;-) Das ist die Lösung.
Vielen Dank!
Viele Grüße
Thorsten
Thorsten Schröer Dipl-Inform (FH) - EDV, Beratung & Service - double-D-IT -Office- / Information system support Bismarckstraße 18a Germany-12169 Berlin Steglitz phone: +49-(0)30-303286770 fax: +49-(0)30-303286779