Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Pomoc w warunkowych zapytaniach SQL

Krótkie i proste pytania przyciągają więcej uwagi niż te długie/złożone. Nie dzieje się tak dlatego, że nie możemy odpowiedzieć, ale przy tak wielu pytaniach i tak małej ilości czasu wolontariusza, który można poświęcić, trudno jest usprawiedliwić czas na przeczytanie ważnych pytań.

Myślę jednak, że twoje podstawowe wymagania nie są aż tak skomplikowane. Potrzebujesz sposobu na pobieranie wierszy, które mieszczą się w zakresie czasu LUB, jeśli nie w tym zakresie, podaj wiersze najbliższe temu zakresowi.

W bazach danych, które obsługują ROW_NUMBER() OVER() jest to dość łatwe (a MySQL 8.x ma to obsługiwać), ale do tego czasu do emulacji row_number() można używać zmiennych i uporządkowanego podzapytania.

Możesz wypróbować to rozwiązanie tutaj pod adresem SQL Fiddle

Konfiguracja schematu MySQL 5.6 :

CREATE TABLE `ponumber` (
  `TimeStr` datetime NOT NULL,
  `Value` int(11) NOT NULL,
  UNIQUE KEY `uk_Times` (`TimeStr`));

INSERT INTO `PONumber`     (`TimeStr`,`Value`) VALUES ('2017-09-28 10:47:55',0);
INSERT INTO `PONumber`     (`TimeStr`,`Value`) VALUES ('2017-09-28 06:26:07',1217911);
INSERT INTO `PONumber`     (`TimeStr`,`Value`) VALUES ('2017-09-28 05:24:18',1217906);

CREATE TABLE `batch_number` (
  `TimeStr` datetime NOT NULL,
  `Value` int(11) NOT NULL,
  UNIQUE KEY `uk_Times` (`TimeStr`));

INSERT INTO `batch_number` (`TimeStr`,`Value`) VALUES ('2017-09-29 12:46:18',5522);
INSERT INTO `batch_number` (`TimeStr`,`Value`) VALUES ('2017-09-29 12:25:33',5521);
INSERT INTO `batch_number` (`TimeStr`,`Value`) VALUES ('2017-09-29 11:44:45',5520);
INSERT INTO `batch_number` (`TimeStr`,`Value`) VALUES ('2017-09-28 06:26:05',5519);
INSERT INTO `batch_number` (`TimeStr`,`Value`) VALUES ('2017-09-28 05:22:58',5518);

CREATE TABLE `batchweight` (
  `TimeStr` datetime NOT NULL,
  `Value` int(11) NOT NULL,
  UNIQUE KEY `uk_Times` (`TimeStr`));

INSERT INTO `batchweight`  (`TimeStr`,`Value`) VALUES ('2017-09-29 12:46:19',38985);
INSERT INTO `batchweight`  (`TimeStr`,`Value`) VALUES ('2017-09-28 06:26:07',38985);
INSERT INTO `batchweight`  (`TimeStr`,`Value`) VALUES ('2017-09-28 05:23:03',31002);

Zapytanie :

SET @bStartTime  := '2017-09-29 11:10:00'   
SET @bEndTime    := '2017-09-29 12:48:00'

SELECT 
      SrcTable, TimeStr, Value
FROM (
      SELECT
            @row_num :=IF( @prev_value=u.SrcTable, @row_num + 1 ,1) AS RowNumber
          , u.*
          , @prev_value := u.SrcTable
      FROM (

          select 'ponumber' SrcTable , TimeStr, `Value`
          from ponumber
          union all
          select 'batch_number' SrcTable , TimeStr, `Value`
          from batch_number
          union all
          select 'batchweight' SrcTable , TimeStr, `Value`
          from batchweight
          ) u
      CROSS JOIN (SELECT @row_num := 1,  @prev_value :='') vars
      ORDER BY SrcTable, TimeStr DESC
      ) d
WHERE (d.TimeStr between @bStartTime and @bEndTime)
   OR (TimeStr < @bStartTime AND RowNumber = 1)

Zatem to, co robi, to obliczanie „RowNumber”, który zaczyna się od 1 dla najnowszego wiersza dla każdej tabeli źródłowej. Następnie ta pochodna tabela jest filtrowana według zakresu czasu lub numeru wiersza, jeśli nie mieści się w zakresie czasu.

Pamiętaj też, że NIE używałem UNION ale zamiast tego użyłem UNION ALL . Istnieje duża różnica w wydajności i należy nauczyć się korzystać z każdego w zależności od potrzeb. Jeśli używasz UNION nie używaj również select distinct ponieważ po prostu marnujesz wysiłek.

Wyniki :

|     SrcTable |              TimeStr | Value |
|--------------|----------------------|-------|
|  batchweight | 2017-09-29T12:46:19Z | 38985 |
| batch_number | 2017-09-29T12:46:18Z |  5522 |
| batch_number | 2017-09-29T12:25:33Z |  5521 |
| batch_number | 2017-09-29T11:44:45Z |  5520 |
|     ponumber | 2017-09-28T10:47:55Z |     0 |



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dostęp do bazy danych MySql z pliku PHP na lokalnym hoście

  2. Zapytanie o interwały dat SQL

  3. 2 pola wprowadzania autouzupełniania/sugestii przy użyciu jQuery lub Ajax z drugim polem opartym na pierwszych wyborach z wieloma elementami

  4. Wybieranie z wielu tabel za pomocą UNION

  5. MySQL 1292 Nieprawidłowa wartość daty i godziny