Advertisement
JanuszKowalski123

OZE - raporty

Apr 24th, 2024 (edited)
33
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
T-SQL 13.66 KB | None | 0 0
  1. --##############################################################################
  2. --"Na jakiej zmianie dane urządzenie OZE uległo awarii"
  3.  
  4. -------------
  5. SELECT df.device_id, df.shift_number
  6. FROM Device_Failures df
  7. ORDER BY df.failure_start;
  8. -------------
  9.  
  10.  
  11.  
  12.  
  13.  
  14. --##############################################################################
  15. --"Na jakiej zmianie urządzenie OZE zostało naprawione"
  16.  
  17. -------------
  18. SELECT r.device_id, df.shift_number
  19. FROM Repairs r
  20. JOIN Device_Failures df ON r.device_id = df.device_id
  21. WHERE r.repair_start BETWEEN df.failure_start AND df.failure_end
  22. ORDER BY r.repair_start;
  23. -------------
  24.  
  25.  
  26.  
  27.  
  28.  
  29. --##############################################################################
  30. --"Jaki był czas przestoju danego urządzenia OZE w ciągu zadanego okresu czasu"
  31.  
  32. -------------
  33. SELECT df.device_id, SUM(DATEDIFF(HOUR, df.failure_start, df.failure_end)) AS downtime_hours
  34. FROM Device_Failures df
  35. GROUP BY df.device_id;
  36. ---------------
  37.  
  38.  
  39.  
  40.  
  41.  
  42. --##############################################################################
  43. --"Jaki był sumaryczny czas postoju wszystkich urządzeń w ciągu zadanego okresu czasu nie wliczając w to sobót i niedziel" - , należy zsumować czasy postoju dla wszystkich urządzeń w tabeli Device_Failures i odfiltrować soboty i niedziele.
  44.  
  45. -------------------------
  46. SELECT SUM(DATEDIFF(HOUR, failure_start, failure_end)) AS TotalDowntimeInHoures
  47. FROM Device_Failures
  48. WHERE DATEPART(WEEKDAY, failure_start) NOT IN (1, 7)  -- 1 - niedziela, 7 - sobota
  49.   AND DATEPART(WEEKDAY, failure_end) NOT IN (1, 7)
  50.   AND DATEDIFF(DAY, failure_start, failure_end) >= 1;  -- Minimalnie jeden dzień trwania awarii
  51. ---------------------------
  52.  
  53. --Zapytanie wybiera sumę czasu postoju wszystkich urządzeń w tabeli Device_Failures, pomijając dni sobotnie i niedzielne oraz awarie trwające mniej niż jeden dzień. Czas postoju jest wyrażony w minutach.
  54. --Dodatkowo, należy upewnić się, że dane w tabeli Device_Failures są poprawne i zawierają pełne informacje o czasie trwania awarii dla wszystkich urządzeń.
  55.  
  56.  
  57.  
  58.  
  59.  
  60. --##############################################################################
  61. --"Czas przestoju danego urządzenia w ciągu zadanego okresu czasu, nie wliczając w to sobót i niedziel" - należy zidentyfikować okresy przestoju urządzenia, które nie kolidują z sobotami i niedzielami, a następnie obliczyć sumę czasu przestoju.
  62.  
  63. -----------------
  64. DECLARE @StartDate DATETIME = '2024-01-01';  -- Data początkowa
  65. DECLARE @EndDate DATETIME = '2024-12-31';    -- Data końcowa
  66.  
  67. SELECT device_id,
  68.        SUM(DATEDIFF(MINUTE, failure_start, failure_end)) AS TotalDowntimeMinutes
  69. FROM Device_Failures
  70. WHERE failure_start >= @StartDate AND failure_end <= @EndDate
  71.   AND DATEPART(WEEKDAY, failure_start) NOT IN (1, 7)  -- Wyklucz soboty (7) i niedziele (1)
  72.   AND DATEPART(WEEKDAY, failure_end) NOT IN (1, 7)
  73. GROUP BY device_id;
  74. --------------------
  75.  
  76. --@StartDate i @EndDate określają zakres czasu, dla którego chcemy obliczyć czas przestoju.
  77. --Warunek WHERE ogranicza wyniki do okresów przestoju, które mieszczą się w zadanym zakresie czasu i nie kolidują z sobotami i niedzielami.
  78. --DATEDIFF(MINUTE, failure_start, failure_end) oblicza różnicę czasu między failure_start i failure_end w minutach dla każdego okresu przestoju.
  79. --SUM agreguje te różnice czasu dla każdego urządzenia, aby obliczyć łączny czas przestoju.
  80. --GROUP BY device_id grupuje wyniki według identyfikatora urządzenia.
  81.  
  82.  
  83.  
  84.  
  85.  
  86. --##############################################################################
  87. --"Które urządzenia psuły się najczęściej" - należy zliczyc liczbę awarii dla każdego urządzenia i posortować wyniki w kolejności malejącej liczby awarii.
  88.  
  89. ----------
  90. SELECT device_id, COUNT(*) AS liczba_awarii
  91. FROM Device_Failures
  92. GROUP BY device_id
  93. ORDER BY liczba_awarii DESC;
  94. -----------------
  95.  
  96. --Zapytanie grupuje awarie według identyfikatora urządzenia (device_id), a następnie zlicza liczbę awarii dla każdego urządzenia. Wyniki są sortowane malejąco według liczby awarii, dzięki czemu na początku listy będą znajdować się urządzenia, które uległy największej liczbie awarii.
  97.  
  98.  
  99.  
  100.  
  101.  
  102. --##############################################################################
  103. --"Które urządzenia miały najdłuższy czas przestoju" - możemy użyć złączenia między tabelą Renewable_Energy_Devices a Device_Failures, a następnie obliczyć czas trwania każdej awarii. Następnie możemy grupować wyniki według identyfikatora urządzenia i obliczyć sumę czasu trwania awarii dla każdego urządzenia. Na końcu możemy posortować wyniki malejąco i wybrać pierwszy rekord, który będzie miał najdłuższy czas przestoju.
  104.  
  105. -------------------------------------
  106. SELECT TOP 1
  107.     d.device_id,
  108.     SUM(DATEDIFF(MINUTE, df.failure_start, df.failure_end)) AS total_downtime_minutes
  109. FROM
  110.     Renewable_Energy_Devices d
  111. JOIN
  112.     Device_Failures df ON d.device_id = df.device_id
  113. GROUP BY
  114.     d.device_id
  115. ORDER BY
  116.     total_downtime_minutes DESC;
  117. -----------------------------------------
  118.  
  119. --Zapytanie wybierze urządzenie z najdłuższym łącznym czasem przestoju w minutach. Jeśli chcemy wyświetlić wynik w innej jednostce czasu, np. godzinach, wystarczy dostosować funkcję DATEDIFF i wynik uzyskany z grupowania.
  120.  
  121.  
  122.  
  123.  
  124.  
  125. --##############################################################################
  126. --"Ile jest procent urządzeń w poszczególnych fazach awarii w stosunku do ilości wszystkich urządzeń", możemy użyć złączenia tabel Renewable_Energy_Devices i Device_Failures, a następnie wykorzystać agregację i funkcje analityczne do obliczenia procentowego udziału urządzeń w poszczególnych fazach awarii.
  127.  
  128. --------------------------------------------------
  129. SELECT
  130.     device_status,
  131.     COUNT(*) AS devices_count,
  132.     CAST(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER () AS DECIMAL(10,2)) AS percentage
  133. FROM
  134.     Renewable_Energy_Devices RED
  135. JOIN
  136.     Device_Failures DF ON RED.device_id = DF.device_id
  137. GROUP BY
  138.     device_status;
  139. --------------------------------------------------
  140.  
  141. --Zpytanie łączy tabelę Renewable_Energy_Devices z tabelą Device_Failures za pomocą kolumny device_id.
  142. Grupuje wyniki według statusu urządzenia (device_status).
  143. --Oblicza liczbę urządzeń w każdej fazie awarii za pomocą funkcji agregującej COUNT(*).
  144. --Wykorzystuje funkcję analityczną SUM(COUNT(*)) OVER (), aby obliczyć sumę wszystkich urządzeń.
  145. --Oblicza procentowy udział urządzeń w poszczególnych fazach awarii.
  146. --Powyższe zapytanie zwróci wyniki, w których każdy wiersz będzie zawierał status urządzenia, liczbę urządzeń w danej fazie awarii oraz procentowy udział tych urządzeń w stosunku do wszystkich urządzeń.
  147.  
  148.  
  149.  
  150.  
  151.  
  152. --##############################################################################
  153. --"Na ilu zmianach nie pracowała maszyna (wliczając to zmianę, na której zgłoszono awarię i na której uruchomiono ją znów produkcyjnie)" - musimy policzyć ilość unikalnych zmian, w których urządzenie znajdowało się w fazie awarii. Wykorzystamy złączenie między tabelą Servicing_Shifts a Device_Failures oraz funkcję COUNT(DISTINCT shift_number) do zliczenia unikalnych numerów zmian.
  154.  
  155. -----------------------------
  156. SELECT
  157.     COUNT(DISTINCT SS.shift_number) AS number_of_shifts_without_device,
  158.     COUNT(*) AS total_shifts
  159. FROM
  160.     Servicing_Shifts SS
  161. LEFT JOIN
  162.     Device_Failures DF ON SS.shift_number = DF.shift_number
  163. WHERE
  164.     DF.failure_id IS NULL OR DF.failure_end IS NOT NULL;
  165. ---------------------------------
  166.  
  167. --Zapytanie łączy tabelę Servicing_Shifts z tabelą Device_Failures za pomocą kolumny shift_number.
  168. --Wykorzystuje LEFT JOIN, aby uwzględnić wszystkie zmiany, niezależnie od tego, czy były związane z awariami.
  169. --Wykorzystuje warunek DF.failure_id IS NULL OR DF.failure_end IS NOT NULL, aby zliczyć tylko te zmiany, w których urządzenie było sprawne (czyli nie było awarii) lub awaria już się zakończyła.
  170. --Używa funkcji COUNT(DISTINCT SS.shift_number) do zliczenia unikalnych numerów zmian, w których urządzenie nie było w fazie awarii.
  171. --Używa funkcji COUNT(*) do zliczenia wszystkich zmian.
  172. --Powyższe zapytanie zwróci wyniki, w których number_of_shifts_without_device będzie zawierać liczbę zmian, w których urządzenie było sprawne, a total_shifts będzie zawierać liczbę wszystkich zmian. Dzięki temu można obliczyć procent zmian, w których urządzenie nie pracowało.
  173.  
  174.  
  175.  
  176.  
  177.  
  178. --##############################################################################
  179. --"Ile jest zamówień do realizacji?" - musimy zliczyć liczbę zamówień, których data zakończenia jest późniejsza niż aktualna data.
  180.  
  181. ------------------------------------
  182. SELECT COUNT(*) AS liczba_zamowien_do_realizacji
  183. FROM Customers_Orders
  184. WHERE customer_order_date_end > GETDATE();
  185. -------------------------------------
  186.  
  187. --Zapytanie wybiera liczbę wierszy z tabeli Customers_Orders.
  188. --Używa warunku WHERE customer_order_date_end > GETDATE(), aby zliczyć tylko te zamówienia, których data zakończenia jest późniejsza niż aktualna data.
  189. --Zapytanie zwróci liczbę zamówień do realizacji.
  190.  
  191.  
  192.  
  193.  
  194.  
  195. --##############################################################################
  196. --"Czy jest możliwe przyjęcie zamówienia - czy uruchomione urządzenia będą wstanie wygenerować oczekiwaną energię" - Aby sprawdzić, czy istnieje możliwość przyjęcia zamówienia dla każdego zamówienia, musimy zsumować moc generowaną przez urządzenia, których status jest równy 0 (czyli działających) i porównać ją z oczekiwaną ilością energii w zamówieniach.
  197.  
  198. -------------------------------------------------------------
  199. DECLARE @oczekiwana_energia DECIMAL(18,0);
  200. DECLARE @customer_order_id INT;
  201. DECLARE @wygenerowana_energia DECIMAL(18,0);
  202.  
  203. DECLARE orders_cursor CURSOR FOR
  204. SELECT customer_order_id, customer_order_amount_of_energy
  205. FROM Customers_Orders;
  206.  
  207. OPEN orders_cursor;
  208. FETCH NEXT FROM orders_cursor INTO @customer_order_id, @oczekiwana_energia;
  209.  
  210. WHILE @@FETCH_STATUS = 0
  211. BEGIN
  212.     SET @wygenerowana_energia = NULL;
  213.  
  214.     SELECT @wygenerowana_energia = SUM(device_power)
  215.     FROM Renewable_Energy_Devices
  216.     WHERE device_status = 0;
  217.  
  218.     IF (@wygenerowana_energia >= @oczekiwana_energia)
  219.         PRINT 'Możliwe jest przyjęcie zamówienia o numerze ' + CAST(@customer_order_id AS VARCHAR(50));
  220.     ELSE
  221.         PRINT 'Nie można przyjąć zamówienia o numerze ' + CAST(@customer_order_id AS VARCHAR(50)) + ' - brak wystarczającej ilości energii';
  222.  
  223.     FETCH NEXT FROM orders_cursor INTO @customer_order_id, @oczekiwana_energia;
  224. END
  225.  
  226. CLOSE orders_cursor;
  227. DEALLOCATE orders_cursor;
  228. ---------------------------------------------------------------------
  229.  
  230. --Zapytanie deklaruje zmienną @oczekiwana_energia, która przechowuje oczekiwaną ilość energii w zamówieniu.
  231. --Deklaruje zmienną @customer_order_id, która przechowuje identyfikator zamówienia.
  232. --Deklaruje zmienną @wygenerowana_energia, która przechowuje sumaryczną moc urządzeń odnawialnych, które są w stanie wygenerować energię.
  233. --Tworzy kursor, aby iterować przez wszystkie zamówienia w tabeli Customers_Orders.
  234. --Dla każdego zamówienia z tabeli, oblicza sumaryczną moc urządzeń o statusie 0 (działających) z tabeli Renewable_Energy_Devices.
  235. --Porównuje sumaryczną moc urządzeń z oczekiwaną ilością energii w zamówieniu.
  236. --Wyświetla odpowiedni komunikat dla każdego zamówienia w zależności od wyniku porównania.
  237.  
  238.  
  239.  
  240.  
  241.  
  242. --##############################################################################
  243. --"Czy awaria danego urządzenia zagraża czasom poprawnej realizacji już zgłoszonych zleceń" - użycie mechanizmu triggera. Trigger pozwala na automatyczne wykonanie określonych działań w odpowiedzi na określone zdarzenia, takie jak dodanie, aktualizacja lub usunięcie danych w tabeli. Trigger ten jest wyzwalany po wstawieniu lub aktualizacji wiersza w tabeli Device_Failures, który wskazuje na awarię urządzenia. Sprawdza on, czy istnieją zlecenia klientów, których daty realizacji kolidują z czasem trwania awarii tego urządzenia. Jeśli takie zlecenia istnieją, trigger wyświetla komunikat o potencjalnym zagrożeniu.
  244.  
  245. ------------------------
  246. CREATE TRIGGER CheckOrderCompletionTime
  247. ON Device_Failures
  248. AFTER INSERT, UPDATE
  249. AS
  250. BEGIN
  251.     DECLARE @device_id NVARCHAR(26);
  252.     DECLARE @failure_start DATETIME;
  253.     DECLARE @failure_end DATETIME;
  254.     DECLARE @order_id INT;
  255.  
  256.     -- Pobierz dane dotyczące nowej awarii
  257.     SELECT @device_id = device_id, @failure_start = failure_start, @failure_end = failure_end
  258.     FROM inserted;
  259.  
  260.     -- Sprawdź, czy istnieją zlecenia klientów, których daty realizacji kolidują z czasem trwania awarii urządzenia
  261.     IF EXISTS (
  262.         SELECT 1
  263.         FROM Customers_Orders
  264.         WHERE (customer_order_date_start BETWEEN @failure_start AND @failure_end
  265.             OR customer_order_date_end BETWEEN @failure_start AND @failure_end
  266.             OR @failure_start BETWEEN customer_order_date_start AND customer_order_date_end
  267.             OR @failure_end BETWEEN customer_order_date_start AND customer_order_date_end)
  268.             -- AND device_id = @device_id   -- tu trzeba by jeszcze uzupełnić tabelę zamówień o pole device_id (mapowanie zamówienia do konkretnego urządzenia)
  269.     )
  270.     BEGIN
  271.         PRINT 'Uwaga! Awaria urządzenia ' + @device_id + ' może zagrażać czasom poprawnej realizacji zleceń.';
  272.     END
  273. END;
  274. -------------------------------
  275.  
  276. --Trigger można dostosować do konkretnych potrzeb i warunków biznesowych, które mają być uwzględnione podczas sprawdzania zagrożenia dla realizacji zleceń.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement