sql >> Database >  >> RDS >> Mysql

Voorwaardelijke hulp bij SQL-query's

Korte en eenvoudige vragen krijgen doorgaans meer aandacht dan lange/complexe. Dit is niet omdat we geen antwoord kunnen geven, maar met zoveel vragen en zo weinig vrijwilligerstijd om te geven, is het moeilijk om de tijd te rechtvaardigen om grote vragen te lezen.

Maar ik denk dat je basisvereiste niet zo ingewikkeld is. U wilt een manier om rijen op te halen die binnen een tijdbereik vallen OF, indien niet in dat bereik, de rijen die het dichtst bij dat bereik liggen.

In databases die ROW_NUMBER() OVER() ondersteunen is dit vrij eenvoudig (en MySQL 8.x is gepland om dit te ondersteunen), maar tot die tijd kun je om row_number() te emuleren variabelen en een geordende subquery gebruiken.

U kunt deze oplossing hier uitproberen op SQL Fiddle

MySQL 5.6 Schema-instellingen :

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);

Zoekopdracht :

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)

Dus wat dit doet, is een "Rijnummer" berekenen dat begint bij 1 voor de meest recente rij voor elke brontabel. Vervolgens wordt deze afgeleide tabel gefilterd op het tijdbereik of op het rijnummer, indien niet binnen het tijdbereik.

Merk ook op dat ik NIET gebruikt UNION maar hebben in plaats daarvan UNION ALL . gebruikt . Er is een groot verschil in prestaties en zou moeten leren om elk naar behoefte te gebruiken. Bij gebruik van UNION gebruik niet ook select distinct omdat je gewoon moeite verspilt.

Resultaten :

|     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. Kan een Android-app rechtstreeks verbinding maken met een online mysql-database?

  2. Kolom toevoegen OF verwijderen uit CDC-geactiveerde tabel zonder gegevens te verliezen in SQL Server-database - SQL Server-zelfstudie

  3. Oracle datum naar string conversie

  4. Oracle 12c Installation heeft geen toegang tot de tijdelijke locatie